select、poll、epoll之间的区别总结

IO多路复用之select、poll、epoll之间的区别总结 select、poll、epoll都是IO多路复用的机制。IO多路复用就是通过一种机制,让一个进程/线程可以监视多个描述符,一旦某个描述符就绪(一般是读写就绪),能够通知应用程序进行相应的读写操作。I/O复用虽然能同时监听多个文件描述符,当其本质上还是同步IO模型,因为需要在读写事件就绪后程序自己负责进行读写事件的处理,而这个读写过程是阻塞的。如果要实现并发,只能使用多进程/多线程等编程手段了。 ... 阅读详情

0. 背景

本文摘自 http://www.cnblogs.com/Anker/p/3265058.html

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。关于这三种IO多路复用的用法,前面三篇总结写的很清楚,并用服务器回射echo程序进行了测试。连接如下所示:

select:http://www.cnblogs.com/Anker/archive/2013/08/14/3258674.html

poll:http://www.cnblogs.com/Anker/archive/2013/08/15/3261006.html

epoll:http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html

今天对这三种IO多路复用进行对比,参考网上和书上面的资料,整理如下:

1. select实现

select的调用过程如下所示:

这里写图片描述

(1)使用copy_from_user从用户空间拷贝fd_set到内核空间

(2)注册回调函数__pollwait

(3)遍历所有fd,调用其对应的poll方法(对于socket,这个poll方法是sock_poll,sock_poll根据情况会调用到tcp_poll,udp_poll或者datagram_poll)

(4)以tcp_poll为例,其核心实现就是__pollwait,也就是上面注册的回调函数。

(5)__pollwait的主要工作就是把current(当前进程)挂到设备的等待队列中,不同的设备有不同的等待队列,对于tcp_poll来说,其等待队列是sk->sk_sleep(注意把进程挂到等待队列中并不代表进程已经睡眠了)。在设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,这时current便被唤醒了。

(6)poll方法返回时会返回一个描述读写操作是否就绪的mask掩码,根据这个mask掩码给fd_set赋值。

(7)如果遍历完所有的fd,还没有返回一个可读写的mask掩码,则会调用schedule_timeout是调用select的进程(也就是current)进入睡眠。当设备驱动发生自身资源可读写后,会唤醒其等待队列上睡眠的进程。如果超过一定的超时时间(schedule_timeout指定),还是没人唤醒,则调用select的进程会重新被唤醒获得CPU,进而重新遍历fd,判断有没有就绪的fd。

(8)把fd_set从内核空间拷贝到用户空间。

总结:select的几大缺点:

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3)select支持的文件描述符数量太小了,默认是1024

2 poll实现

poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。

int poll (struct pollfd *fds, unsigned int nfds, int timeout);

不同与select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。

struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events to watch */
    short revents; /* returned events witnessed */
};

pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。

关于select和poll的实现分析,可以参考下面几篇博文:

http://blog.youkuaiyun.com/lizhiguo0532/article/details/6568964#comments

http://blog.youkuaiyun.com/lizhiguo0532/article/details/6568968

http://blog.youkuaiyun.com/lizhiguo0532/article/details/6568969

http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/index.html?ca=drs-

http://linux.chinaunix.net/techdoc/net/2009/05/03/1109887.shtml

3、epoll

epoll既然是对select和poll的改进,就应该能避免上述的三个缺点。那epoll都是怎么解决的呢?在此之前,我们先看一下epoll和select和poll的调用接口上的不同,select和poll都只提供了一个函数——select或者poll函数。而epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait。

int epoll_create(int size);//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

1). int epoll_create(int size);

创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大,这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值,参数size并不是限制了epoll所能监听的描述符最大个数,只是对内核初始分配内部数据结构的一个建议。

当创建好epoll句柄后,它就会占用一个fd值,在linux下如果查看/proc/process_id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。

2). int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

函数是对指定描述符fd执行op操作。

  • epfd:是epoll_create()的返回值。
  • op:表示op操作,用三个宏来表示:添加EPOLL_CTL_ADD,删除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。分别添加、删除和修改对fd的监听事件。
    -fd:是需要监听的fd(文件描述符)
  • epoll_event:是告诉内核需要监听什么事,struct epoll_event结构如下:
struct epoll_event {
  __uint32_t events;  /* Epoll events */
  epoll_data_t data;  /* User data variable */
};

//events可以是以下几个宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里

3). int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待epfd上的io事件,最多返回maxevents个事件。

参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。该函数返回需要处理的事件数目,如返回0表示已超时。

对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。

对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。

对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。

4. 总结

(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。

参考资料:

http://www.cnblogs.com/apprentice89/archive/2013/05/09/3070051.html

http://www.linuxidc.com/Linux/2012-05/59873p3.htm

http://xingyunbaijunwei.blog.163.com/blog/static/76538067201241685556302/

http://blog.youkuaiyun.com/kkxgx/article/details/7717125

https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c

保姆级教程:用MediaPipe和BlazePose在Python里实时追踪你的健身动作(附完整代码) 本文提供了一份详细的Python教程,教你如何使用MediaPipe和BlazePose实现实时健身动作追踪。从环境配置、模型选型到实时视频流处理架构设计,再到健身动作量化分析和可视化反馈系统优化,教程涵盖了完整的实现步骤和代码示例,帮助开发者快速构建高效的姿态特征点检测系统。 阅读详情

相关推荐

python爬虫自动下载网页链接

需求分析 今天遇到一个简单的需求,需要下载澳大利亚电力市场NEM日前市场的发电商报价数据(http://nemweb.com.au/Reports/Current/Next_Day_Offer_Energy/),页面观感是这样的: Ctrl + F 一下,看到一共有395个zip链接。于是就想着用python爬虫自动下载。这个网页很简单,没有验证码,甚至不需要登录,因此自动下载的pytho...

da_kao_la的博客 1万+

select 与 epoll的区别

内核实现机制不同:select 是系统调用,每次调用都需要把全部描述符集合从用户态传输到内核态,并且需要判断每个描述符是否就绪;epoll 则是内核空间与用户空间共享一块内存,只需要在内核空间注册一个事件表,然后等待事件的通知即可,不需要对已注册的文件描述符进行遍历。文件描述符数量限制不同:select 的文件描述符数量被限制在 1024 左右,对于大规模的连接,需要使用 fd_set 多次扩展或者使用其他的多路复用技术;而 epoll 是基于事件驱动的模型,通过回调函数只处理活跃的文件描述符,效率更高。

QtCompany的博客 2959

FunASR与FreeSWITCH融合实战:从零构建高精度语音质检系统

本文详细介绍了如何将FunASR与FreeSWITCH融合,构建高精度语音质检系统。通过实时语音听写技术,结合热词定制和多模型切换,实现客服中心等场景的自动化质检,显著提升识别准确率和效率。系统架构涵盖音频采集、识别处理和业务应用三层,支持负载均衡和性能优化,适用于工业级部署。

weixin_29198045的博客 980

IO多路复用之select&epoll

io多路复用之selectepoll笔录

weixin_42754971的博客 3112

2024年最新双摄像头的实时视频拼接及目标跟踪(一)_监控视频拼接实时(1),网络相关+C C++三方库的源码分析+数据结构与算法

opencv中采用了SURF,ORB进行特征点提取,如果装的是opencv2.0版本,则可以直接用SURF,如果是3.0版本,则需要下载相应的contrib库进行安装。原理不赘述,给出其实验结果对比和分析,原始图像1SURF特征点提取网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以添加戳这里获取一个人可以走的很快,但一群人才能走的更远!

m0_51437227的博客 937

LangGraph实战:如何用循环机制优化你的LangChain Agent工作流

本文详细介绍了如何使用LangGraph的循环机制优化LangChain Agent工作流,解决传统AgentExecutor在强制工具调用、动态提示调整和多阶段循环中的局限性。通过状态机和显式状态图设计,LangGraph提供了更精准的流程控制能力,适用于复杂AI应用场景。

weixin_30316097的博客 487

select、poll、epoll详解

https://blog.youkuaiyun.com/shawntime/article/details/115089947 IO读写基本原理 用户程序进行IO操作实际依赖于linux系统内核read()、write()函数 read()函数的调用并不是直接从网卡把数据读取到用户内存中,而是把内核缓冲区中的数据复制到用户缓冲区中 write()函数的调用也并不是直接把数据写入网卡中,而是把用户缓冲区的数据写入到内核缓冲区中 网卡与内核缓冲区数据的读写则是由操作系统内核完成 阻塞IO和非阻塞IO

yygr的博客 1万+

自适应IIR格型滤波器的Matlab实现

概述 在现有的众多抑制窄带干扰的信号处理手段中,时域自适应陷波干扰抑制技术具有实现简单、抗干扰性能好等优点。IIR陷波器按照结构可以分为直接型和格型两种。相比自适应直接型IIR陷波器,自适应格型IIR陷波器不仅可以准确地控制滤波器的陷波频率,也可以准确地调整陷波器的带宽。 传递函数 二阶自适应IIR格型陷波器的传递函数H(z)为: 其中α与陷波带宽有关,β与陷波频率有关;对应的结构如下图所示: Matlab算法实现 ...

剑藏锋的博客 2800

select和epoll的详细区别

selectepollselect和epoll都是 Linux 中用于 I/O 多路复用的机制,但epoll更加高效且适用于大规模并发场景。select的性能会随着监视的文件描述符数量线性下降,而epoll使用事件通知机制,性能几乎不受文件描述符数量的影响。在大多数高并发场景下,epoll是首选;而对于小规模应用或跨平台需求时,可以考虑使用select。通过理解select和epoll的不同特性,可以在不同场景中选择最合适的 I/O 复用技术来实现高效的 I/O 处理。

h52013141的博客 2893

从零开始了解数据采集(五)——工业通信协议:数据采集的“语言”桥梁

数据采集常用的通信协议有哪一些?看完这篇你就了解了~

李恒的博客 4058

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的危险物品检测系统(深度学习模型+PySide6界面+训练数据集+Python代码)

随着公共安全需求的日益增长,危险物品检测技术在社会安防、交通安检等领域发挥着重要作用。本文介绍了一个基于YOLO系列深度学习框架的危险物品检测系统,集成了YOLOv8、YOLOv7、YOLOv6和YOLOv5四种先进的物体检测算法。系统采用PySide6开发了用户友好的图形界面,提供了完整的训练代码、预训练模型和数据集构建方案。实验结果表明,该系统在危险物品检测任务上实现了高精度和高实时性,为实际应用提供了可靠的技术支持。

YOLO 156

I/O多路复用 - select、poll、epoll讲解(epoll工作图解介绍+红黑树)

epoll的实现机制与select/poll机制完全不同。epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。

m0_51429770的博客 3977

基于 Qt C++ 开发一套西门子量子测量系统的控制与数据采集平台

sensorIdCombo->addItems({"QTS-100-001 (温度)", "QPG-200-001 (压力)", "QDS-300-001 (位移)"});precisionTable->setHorizontalHeaderLabels({"传感器ID", "类型", "标称精度", "实际精度", "校准状态"});QWidget *dispWidget = createSensorWidget("量子位移", "mm (±1μm)", 50.0, 0.001);// 传感器状态更新。

寒寒豆豆软件公司的博客 253

select poll epoll之间的区别

前导 首先在分析他们之前的区别前,需要明确几个概念。 同步阻塞、 同步非阻塞 异步非阻塞 同步和异步的概念: 同步是指用户线程发起IO请求后,需要等待或者轮询内核IO操作完成后才能继续执行; 异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程或者调用用户线程注册的回调函数。 阻塞和非阻塞的概念: 阻塞是指IO操作需要彻底完成后才返回到用户空间; 非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。 I/O 同步和异步的区别在于:

m0_61802230的博客 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

select、poll、epoll之间的区别

select、poll、epoll之间的区别 2021-06-22 15:58·一道闪电惊天雷 (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入的数组

weixin_39355187的博客 3440

深度学习工具包 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")

select,poll,epoll之间的关系和区别

文件描述符(File Descriptor,简称FD)是一个抽象的非负整数,用于在操作系统中唯一标识一个打开的文件或其他资源,如管道、设备等。每个进程在执行时,操作系统会为其维护一个文件描述符表,这个表记录了该进程打开的所有文件和其他资源的引用。文件描述符在这个表中作为索引使用,指向表中的一个条目,每个条目包含了资源的相关信息和操作该资源的能力。标识资源:为系统中的每个打开资源提供一个唯一的标识符。简化操作:通过文件描述符,进程可以方便地对文件进行读写操作,而无需关心底层的实现细节。资源管理。

z3551906947的博客 1350

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

select、poll、epoll之间的区别比较

select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。 poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的. epoll

C/C++Linux、音视频、DPDK 8724
上一篇: Python的垃圾回收机制(一)之简介
下一篇: Python实现Event回调机制
tab_space
博客等级 码龄11年 91粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值