拆解 Redis 核心引擎:I/O模型、线程模型

Redis线程模型深度解析:从单线程到多线程I/O的演进与设计哲学 I/O多路复用是高性能网络编程的核心技术,它允许单个线程高效管理大量并发连接,通过事件驱动模型避免了传统阻塞I/O的资源浪费。其原理基于操作系统提供的epoll、kqueue等系统调用,实现高并发下的低延迟响应。这一技术在高性能服务器设计中具有重要价值,尤其适用于需要处理海量短连接的场景,如缓存、消息队列和实时通信服务。Redis正是这一技术的典范应用,它通过单线程命令执行保证数据操作的原子性,同时利用I/O多路复用处理网络并发。随着Redis 6.0引入多线程I/O,网络数据的读写和协议解析被并行化,但核 阅读详情

Redis 之所以能够支撑每秒数万甚至数十万的 QPS,绝不仅仅是因为它是基于内存操作的。更深层次的原因在于其精妙的事件驱动模型和IO处理机制。

本文将深入 Redis 源码层面,拆解其核心运行机制(Engine),带你理解 AeEventLoop、Reactor 模式以及 Redis 线程模型的演进之路。


1. 核心基石:Redis 的事件模型 (AeEventLoop)

Redis 是一个事件驱动程序。服务器运行的本质就是一个死循环(Event Loop),在这个循环中不断地等待事件发生、处理事件。

1.1 IO 多路复用与 Reactor 模式

Redis 并没有为每个客户端连接创建一个线程(这是传统 BIO 模型的做法),而是利用了 IO 多路复用技术(IO Multiplexing)。

  • 概念:单个线程通过记录跟踪每一个 Socket(I/O流)的状态来同时管理多个 I/O 流。
  • 实现:在 Linux 下主要依赖 epoll,macOS 下依赖 kqueue。Redis 封装了一套 ae.c 事件库来屏蔽底层操作系统的差异。
  • 模式:这就是典型的 Reactor 模式。Redis 作为 Reactor(反应堆),当 Socket 可读或可写时,分发给相应的处理器(Handler)。

Redis Server (Main Thread)

Fired Events

Connect

Read

Write

SYN

CMD: GET

CMD: SET

IO Multiplexing (epoll_wait)

Event Dispatcher

Accept Handler

Read Handler

Write Handler

Client 1

Client 2

Client 3

1.2 源码透视:ae.c 与 ae_epoll.c

在 Redis 源码中,aeEventLoop 结构体是整个事件循环的核心。

核心结构体 (ae.h):

typedef struct aeEventLoop {
    int maxfd;   /* 当前注册的最大文件描述符 */
    int setsize; /* 关注的文件描述符上限 */
    aeFileEvent *events; /* 注册的文件事件 */
    aeFiredEvent *fired; /* 已触发的事件(被epoll唤醒后填充) */
    // ... 省略时间事件等
    void *apidata; /* 用于存储底层API的数据,如epoll_event结构 */
} aeEventLoop;

主循环逻辑 (ae.c):
Redis 的 main 函数最终会调用 aeMain,启动死循环。

void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        // 如果有需要在事件循环前执行的函数(如 flushAppendOnlyFile)
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);

        // 核心:处理文件事件和时间事件
        aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
    }
}

epoll 的封装 (ae_epoll.c):
aeProcessEvents 内部会调用 aeApiPoll,即 epoll_wait。

static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    // 调用操作系统的 epoll_wait,获取就绪的事件
    // state->events 是 struct epoll_event 数组
    int retval = epoll_wait(state->epfd, state->events, eventLoop->setsize,
            tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
            
    // ... 将内核返回的就绪事件,填充到 eventLoop->fired 数组中
    return retval;
}

2. 全景图解:一条命令的执行流程

理解了事件循环,我们来看看当客户端发送一个 SET key value 命令时,Redis 内部发生了什么。

2.1 执行步骤

  1. 建立连接:客户端发起连接,服务端 listen fd 触发读事件,调用 acceptTcpHandler 建立连接,并创建一个 client 对象,注册 readQueryFromClient 读事件处理器。
  2. 读取请求:当客户端发送数据,Socket 可读,触发 readQueryFromClient,将数据读入输入缓冲区(querybuf)。
  3. 协议解析:解析 RESP 通信协议,识别命令和参数。
  4. 命令查找:根据命令名称(如 “SET”)在命令表(Command Table)中查找对应的函数。
  5. 执行命令:调用对应的命令函数(如 setCommand),操作内存数据结构(dict)。
  6. 写入回复:将结果写入输出缓冲区(buf 或 reply 链表),并注册写事件(如果数据量大)。
  7. 发送结果:当 Socket 可写时,sendReplyToClient 将数据发送回网卡。

2.2 时序图演示

Command Execution Networking (read/write) AeEventLoop (epoll) Socket Client Command Execution Networking (read/write) AeEventLoop (epoll) Socket Client opt [输出缓冲区已满或需要在下一- 次循环发送] 发送命令 (SET k v) 触发 Socket 可读事件 调用 readQueryFromClient read() 读取数据到 buffer 解析 RESP 协议 调用 processCommand lookupCommand (查找命令表) 执行 setCommand (内存操作) addReply (结果写入输出缓冲区) 注册 Socket 可写事件 触发 Socket 可写事件 调用 sendReplyToClient 发送响应数据 (+OK)

3. 线程模型的演进:从单线程到多线程 IO

“Redis 是单线程的”这句话在 Redis 6.0 之后不再完全准确。我们需要从历史演进的角度来看待这个问题。

3.1 Redis 4.0 之前:纯粹的单线程?

实际上,Redis 一直都有后台线程(BIO Thread)。

  • 主线程:负责接收连接、解析请求、读写 Socket、执行命令、定时任务。
  • 后台线程:主要用于耗时的文件操作,如 fsync(AOF刷盘)。

3.2 Redis 4.0:Lazy Free 的引入

为了解决删除大 Key(如几百万元素的 Hash)导致主线程阻塞的问题,Redis 4.0 引入了 UNLINK 命令和 FLUSHALL ASYNC。

  • 机制:将释放内存的操作通过 bio_job 扔给后台线程异步执行,主线程只做逻辑删除。

3.3 Redis 6.0:多线程 IO (Threaded I/O)

为什么引入多线程?
随着网络硬件的发展,Redis 的瓶颈逐渐从 CPU 转移到了 网络带宽 和 网络 I/O 处理(Socket 的读写和协议解析)。

核心设计理念:
Redis 6.0 的多线程仅仅用于 网络数据的读写和协议解析,而 命令的执行(内存操作)依然是单线程的。

  • 这样做的好处:
    1. 无需引入复杂的锁机制,保证了数据操作的原子性。
    2. 解决了网络 IO 的瓶颈。
    3. 代码复杂度增加可控。
多线程 IO 流程图

Redis 6.0 Threading Model

IO Threads (Worker Threads)

1. Distribute Reads
1. Distribute Reads
1. Distribute Reads
2. Offload Parsing
2. Offload Parsing
2. Offload Parsing
3. Parsed Cmds
3. Parsed Cmds
3. Parsed Cmds
4. Execute Commands (Atomic)
5. Distribute Writes
5. Distribute Writes
5. Distribute Writes
6. Write to Socket
6. Write to Socket
6. Write to Socket

IO Thread 1

Client Socket 1

Main Thread

Client Socket 2

Client Socket 3

IO Thread 2

IO Thread 3

源码关键点 (networking.c):

Redis 在 beforeSleep 中处理多线程读写分配:

  • handleClientsWithPendingReadsUsingThreads: 将等待读取的客户端分配给 IO 线程。
  • handleClientsWithPendingWritesUsingThreads: 将等待写入的客户端分配给 IO 线程。
  • Busy Wait: 主线程在分配完任务后,会自旋等待所有 IO 线程完成工作,然后再统一执行命令。

4. 总结:Redis 为什么这么快?

通过对引擎的拆解,我们可以归纳出 Redis 高性能的“三驾马车”:

Redis 高性能秘密

内存操作

纯内存访问

纳秒级延迟

优秀的 IO 模型

Epoll

非阻塞 IO

Redis 6.0 多线程 IO 加持

高效的数据结构

简单动态字符串

压缩列表

跳表

单线程执行优势

避免上下文切换

无锁竞争

I/O多路复用与异步I/O本质区别:从epoll到io_uring的演进逻辑 I/O模型是操作系统与应用程序交互的核心机制,涉及阻塞、非阻塞、I/O多路复用和异步I/O四大范式。其底层原理围绕数据拷贝路径、上下文切换开销及事件通知方式展开:传统阻塞I/O受限于线程膨胀,非阻塞需配合事件通知才能实用;I/O多路复用(如epoll)通过内核就绪通知实现单线程高并发管理,属同步语义但支撑异步编程模型;而真正异步I/O(如io_uring)则通过共享内存环形队列、零拷贝提交与完成,消除系统调用与上下文切换,达成数据直通设备。技术价值在于突破C10K/C100K瓶颈,适用于Web服务器、实时交 阅读详情

相关推荐

Redis高性能设计解析:内存、单线程与I/O多路复用的工程实践

在分布式系统与高并发场景中,缓存技术是提升应用性能的核心组件。其基本原理是将高频访问的数据存储在访问速度更快的介质中,减少对慢速存储(如磁盘数据库)的依赖,从而显著降低数据访问延迟。从技术价值看,优秀的缓存系统能有效解决数据库瓶颈,提升系统吞吐量和响应速度。在应用场景上,缓存广泛用于会话管理、热点数据存储、排行榜和消息队列等。Redis作为内存数据存储的代表,其高性能源于多维度设计:内存存储提供纳秒级访问速度;高效数据结构如SDS和哈希表优化了内存使用与操作效率;单线程模型避免了锁竞争与上下文切换;结合I/

chutisun0039的博客 431

Redis(一)——Redis核心数据结构和高性能原理

redis入门与核心原理

yemuxiaweiliang的博客 571

Java I/O模型穿透指南:从Linux系统调用到WebFlux实战

I/O模型是后端性能的底层基石,其本质是操作系统对文件描述符的调度策略——阻塞/非阻塞由O_NONBLOCK标志控制,同步/异步反映API结果获取方式。理解epoll_wait、read系统调用与JVM线程状态(如WAITING/RUNNABLE)的映射关系,才能真正诊断高并发下的RT毛刺与线程堆积。NIO通过事件驱动提升连接复用率,而WebFlux依赖Reactive生态实现全链路非阻塞;但若混用JDBC等阻塞调用,将触发BlockingOperationError。本文结合strace、jstack、s

as2886089的博客 390

Redis的三种模式

一、Redis模式 Redis有三种模式:分别是主从同步/复制、哨兵模式、Cluster 主从复制:主从复制是高可用Redis的基础,哨兵和群集都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单故障恢复。缺陷:故障恢复无法自动化,写操作无法负载均衡,存储能力受到单机的限制。哨兵:在主从复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均...

mcl914的博客 1076

Node.js vs Rails技术选型实战指南:从I/O模型到MVP上线决策

Web后端框架选型本质是运行模型与业务负载的匹配问题。Node.js基于事件循环的异步I/O模型天然适配高并发、低延迟、外部依赖密集型场景;Rails依托多进程+GIL的同步阻塞模型,在复杂业务逻辑、强数据一致性、快速MVP交付等场景中具备显著工程效率优势。二者差异不在抽象性能参数,而在于CPU密集型任务处理能力、错误定位成本、生态契约完备性及团队调试范式适配度。真实项目中,应依据TTFB占比、上线周期、数据模型稳定性、运维监控习惯等5个实操维度动态决策,而非追求单一‘最优解’。本文结合17个生产系统经验,

weixin_30298497的博客 338

C# Stream底层契约与高并发I/O实战解析

Stream是.NET中I/O操作的核心抽象,其本质并非数据管道,而是一组运行时能力契约(CanRead/CanWrite/CanSeek等),直接影响异步行为、资源释放和跨平台兼容性。理解其状态机语义、Dispose与Close的差异、缓冲区管理策略及CancellationToken穿透机制,是构建高吞吐、低延迟、抗压型流式系统的前提。尤其在文件上传、日志分析、实时音视频转发等场景中,错误假设Stream可Seek或忽略BufferedStream.Flush缺失,极易引发数据丢失与超时雪崩。本文聚焦S

unixboy 559

介绍一下redis中底层磁盘及IO模型,数据持久化机制,哨兵机制

AOF:AOF是一种日志的方式,会将每个写操作追加到一个文件的末尾,以此来记录所有的写操作。当需要恢复数据时,只需重新执行文件中的写操作即可。AOF:AOF是一种日志的方式,会将每个写操作追加到一个文件的末尾,以此来记录所有的写操作。AOF文件存储的是所有的写操作,可以通过重放AOF文件中的写操作来恢复数据。底层磁盘及IO模型: Redis中的数据存储在内存中,但为了保证数据的持久化,Redis还提供了两种数据持久化方式:RDB(Redis DataBase)和AOF(Append-Only File)。

qq_38366111的博客 1189

【AHC】深度解构:HttpAsyncClient 与 async-http-client(AHC)的三大架构差异

摘要: Apache HttpAsyncClient与AsyncHttpClient(AHC)在异步HTTP客户端架构上存在本质差异。HttpAsyncClient基于Java原生NIO,缺乏内存池管理,易引发堆外内存泄漏,且回调逻辑阻塞I/O线程;而AHC依托Netty,支持内存复用、非阻塞DNS及HTTP/2,通过EventLoop线程模型实现高效回调分发。实际案例中,HttpAsyncClient在高并发场景下因Direct Memory泄漏导致Flink作业OOM,切换至AHC后问题解决。两者差异体

九师兄 61

Redis 从表层逐渐深入底层

什么是 Redis? Redis 代表REmote DIctionary Server。它由 Salvatore Sanfilippo 在 2006 年用 C 语言编写。它是一个 NoSQL 高级键值数据存储。Redis 中的读写操作非常快,因为它将所有数据存储在内存中。数据也可以存储在磁盘上,也可以写回内存。 它通常被称为数据结构服务器,因为键可以包含字符串、散列、列表、集合、排序集合、位图和超日志。 NoSQL 意味着not only SQL。NoSQL 数据库不定义像表这样的数据库结构,也不支持查询,

CodeDoraemon的博客 1322

FPGA图像处理入门 ZYNQ7020 图像中值膨胀腐蚀滤波

图像处理的三种滤波 中值滤波应用较为广泛 综合膨胀和腐蚀可以实现边缘检测。

Coast_的博客 715

【GAN实战】基于pytorch-CycleGAN与pix2pix的自定义数据集训练全攻略

本文详细解析了基于PyTorch的CycleGAN与pix2pix模型在自定义数据集上的完整训练流程。核心在于根据数据是否成对来正确选择模型:pix2pix适用于严格配对的“孪生”数据,而CycleGAN则擅长处理非配对的“散装”数据集。文章从数据准备、配置训练到测试应用,提供了全链路实战指南与关键参数调优心得,帮助开发者高效实现图像到图像的风格转换。

x2y3z4a5b的博客 704

Redis深入理解-内核请求处理流程、数据传输协议

AOF 将内存数据同步到磁盘中,一般采用每秒同步一次,如果同步频率过高,就会导致 Redis 性能退化,当 Redis 突然宕机,可能会丢失 1s 内的内存数据,那么在 redis-server 进程重启时,就会把磁盘存储的 aof 文件的数据给读取到内存中,还原 Redis 上次运行时的内存情况。中,那么在上边的 argv 中拿到了命令的名称,就可以去命令查找表中去查找对应的 RedisCommand,在 Redis Client 的输入缓冲区中有一个变量。

qq_45260619的博客 1689

全面分析总结解决Could not transfer artifact org.apache.maven.plugins等此类问题的方法

全面分析总结解决Could not transfer artifact org.apache.maven.plugins,Could not transfer artifact xxx from/to xxx等此类问题的方法

ccjjjjdff的博客 1万+

【分布式利器:Redis】2、单线程Redis高并发原理:I/O多路复用+3大优化点(附多线程对比)

Redis单线程高并发原理解析:I/O多路复用+三大优化策略 Redis采用单线程模型却能支撑10万+QPS,核心在于精准把握I/O密集型场景特性。首先通过I/O多路复用技术(Linux下采用epoll)实现单线程高效管理大量连接,仅处理就绪事件避免资源浪费。同时依托三大优化:纯内存操作(微秒级响应)、精心设计的数据结构(降低操作复杂度)以及规避多线程开销(无锁竞争和上下文切换)。相比多线程方案,该模式在I/O密集场景下资源消耗更低、CPU利用率更高且实现更简单。通过这三重技术组合,Redis单线程性能达到

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 1328

四旋翼滑模控制:从理论到Simulink实现

本文深入探讨了四旋翼滑模控制的理论与Simulink实现,对比了其相较于PID控制在抗干扰和鲁棒性方面的显著优势。文章详细介绍了从精确动力学建模、内外环滑模控制器设计到指令解算的完整流程,并分享了Simulink仿真搭建、参数调试及抗扰性能验证的实战经验,帮助工程师掌握在复杂环境下提升四旋翼稳定性的进阶技能。

weixin_29163581的博客 375

【DRAM存储器五十一】LPDDR5介绍--DFE与Pre-Emphasis

简述LPDDR5的DFE和预加重应用设置

highman110的博客 705

异步I/O实战:Python高性能Web服务优化指南

异步I/O是现代Web服务应对高并发I/O等待的核心机制,其本质是利用事件循环(如epoll/kqueue)替代线程阻塞,实现单线程内高效调度成千上万网络/数据库/磁盘请求。相比多线程模型,它显著降低内存开销与上下文切换成本,尤其适配Python生态中FastAPI、asyncpg、httpx、aioredis等原生异步工具链。技术价值在于提升QPS、压降P95延迟、增强系统吞吐稳定性,广泛应用于电商秒杀、实时数据看板、物联网平台等I/O密集型场景。本文聚焦真实项目中的异步I/O落地实践,涵盖连接池调优、H

weixin_33907511的博客 369

自私兽群优化器(SHO)详解:从生物本能到智能优化

自私兽群优化器(SHO)是一种受动物群体自私行为启发的智能优化算法。该算法模拟动物在捕食威胁下的两种行为:聚集行为(全局搜索)和自私行为(局部搜索),将优化问题的解空间映射为生存环境,候选解视为猎物个体。SHO通过安全性评估将猎物分为安全、危险和高危三类,分别采用不同的位置更新策略,并引入捕食者角色增加选择压力。相比传统优化算法,SHO具有无需梯度信息、自适应平衡探索与开发、参数简单等优势,特别适合高维复杂和多模态优化问题。算法通过马尔可夫链理论保证收敛性,已在工程设计和数据挖掘等领域展现出良好性能。

qq_42212808的博客 196

【Redis合集-04】Redis 单线程模型深度拆解:事务、管道、Lua 与大 Key 治理

学习Redis关于事务、管道、Lua 与大 Key 治理

记录日常技术学习,分享后端学习笔记 623

Microsemi Libero使用技巧1——查看芯片资源占用情况

Microsemi Libero使用技巧——查看芯片资源占用情况 前言 与MCU不同,FPGA的资源主要包括:逻辑资源,IO资源,Flash大小,PLL资源,SoC硬核处理器资源等,其中逻辑资源和IO资源是我们主要关心的,本篇文章将介绍,如何通过Microsemi Libero IDE来查看工程的详细资源占用情况。 A2F200M3F的资源 以Microsemi SmartFusion系列A2F2...

whik1194的博客 5694

Python爬虫实战:爬取小红书数据做爆款分析,我破解了签名加密+移动端反爬(附完整代码)

爬取小红书数据的核心,不是“简单的HTTP请求”,而是“理解移动端接口的加密逻辑和反爬规则”——从x-s/x-t签名破解到移动端UA伪装,再到行为模拟,每一步都是对移动端爬虫的深度理解。这套方案的价值在于,不仅能稳定抓取小红书数据,还能从数据中拆解出有价值的爆款特征,真正把“数据”变成“洞察”。对程序员来说,小红书爬虫不仅是技术练手,更是了解新媒体平台数据逻辑的窗口。希望这篇分享能帮到做新媒体分析或爬虫进阶的小伙伴,也欢迎在评论区交流小红书反爬和爆款分析的更多技巧!

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2057

Node.js事件循环与单线程真相:I/O密集型架构核心解析

Node.js常被误读为‘单线程阻塞模型’,实则是基于事件驱动的异步I/O调度系统。其核心在于事件循环(Event Loop)协调JavaScript主线程、V8引擎、libuv线程池与操作系统内核四层协作,将耗时操作卸载至后台,实现高并发低延迟。这种设计天然适配I/O密集型场景——如实时通信、API网关、流式数据处理,但不擅CPU密集型任务。理解event loop阶段(timers、poll、check等)与微任务/宏任务执行顺序,是避免回调地狱、定时器失准、长尾延迟等生产问题的关键。结合V8内存机制与

weixin_30765505的博客 332

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Redis底层视角拆解:缓存穿透/击穿/雪崩 高并发防御全指南

本地缓存挡热点,Redis 缓存挡 DB,DB 做兜底——通过"层层拦截"让请求在最快的地方被处理,同时用随机 TTL 和故障降级来抵御雪崩风险。这是一个典型的用空间换时间、用复杂度换性能的方案,适合读多写少的高并发场景。

qq_23277595的博客 298

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Day680.大佬如何学习源码 -深入拆解 Tomcat & Jetty

带着这些问题去分析相关的源码效率会更高,同时你在寻找答案的过程中,也会碰到更多问题,等你把这些问题都弄清楚了,你获得的不仅仅是知识,更重要的是你会树立起攻克难关的信心。当你对知识有了一定的积累,这时再来学一个新的系统,往往你只需要瞧上几眼,就能明白它所用的架构,而且你会自然联想到系统存在哪些角色,以及角色之间的关系,包括静态的依赖关系和动态的协作关系,甚至你会不由自主带着审视的眼光,来发现一些可以改进的地方。当然在这个过程中,你还可以看看产品的官方文档,熟悉一下大概的设路。...

阿昌爱Java 1270

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

muduo网络库为什么高性能?

摘要:本文针对C++开发者学习muduo网络库时常见的问题,提出要深入理解其高性能原理而非简单模仿。muduo的高性能源于四大核心设计:1)四种可配置线程模型(单Reactor单线程、单Reactor多线程、多Reactor多线程及混合模型);2)epoll的LT模式选择;3)Reactor事件处理模式;4)内存与数据结构优化(如readv缓冲区、TimerQueue定时器管理)。文章通过源码分析和性能测试(如thread_local缓存线程ID优化)展示设计细节,并指导面试时应从架构到细节全面阐述原理,避

2401_86353562的博客 483

(多线程性能优化黄金法则):构建高吞吐低延迟量化引擎的7个关键步骤

掌握量化交易系统的多线程并发控制,提升引擎性能。本文详解高吞吐低延迟系统构建的7个关键步骤,涵盖线程池管理、锁优化与无锁队列应用,适用于高频交易场景。显著降低延迟、提高稳定性,值得收藏。

CodeWhim的博客 959
上一篇: 深入Redis内核:揭秘高性能背后的底层数据结构
下一篇: 走近Python爬虫(一):爬虫的作用和技术、获取网页内容、解析网页内容
TracyCoder123
博客等级 码龄8年 1万+粉丝 226原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TracyCoder123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值