【Netty 专栏】Netty源码分析之NioEventLoop

Java读源码之Netty深入剖析 使用一个简单的socket例子概括Netty里面的基本组件,包括NioEventLoop,Channel,ByteBuf,Pipeline,ChannelHandler。。。。点击↓↓↓百度快照 阅读详情

点击上方“芋道源码”,选择“置顶公众号”

技术文章第一时间送达!

源码精品专栏

 

上一章节中,我们分析了Netty服务的启动过程,本章节分析Netty的NioEventLoop是如工作的。

img

NioEventLoop中维护了一个线程,线程启动时会调用NioEventLoop的run方法,执行I/O任务和非I/O任务:

I/O任务
即selectionKey中ready的事件,如accept、connect、read、write等,由processSelectedKeys方法触发。

非IO任务
添加到taskQueue中的任务,如register0、bind0等任务,由runAllTasks方法触发。

两种任务的执行时间比由变量ioRatio控制,默认为50,则表示允许非IO任务执行的时间与IO任务的执行时间相等。

NioEventLoop.run 方法实现

protected void run() {
   for (;;) {
       boolean oldWakenUp = wakenUp.getAndSet(false);
       try {
           if (hasTasks()) {
               selectNow();
           } else {
               select(oldWakenUp);
               if (wakenUp.get()) {
                   selector.wakeup();
               }
           }
           cancelledKeys = 0;
           needsToSelectAgain = false;
           final int ioRatio = this.ioRatio;
           if (ioRatio == 100) {
               processSelectedKeys();
               runAllTasks();
           } else {
               final long ioStartTime = System.nanoTime();
               processSelectedKeys();
               final long ioTime = System.nanoTime() - ioStartTime;
               runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
           }
           if (isShuttingDown()) {
               closeAll();
               if (confirmShutdown()) {
                   break;
               }
           }
       } catch (Throwable t) {
           logger.warn("Unexpected exception in the selector loop.", t);
           // Prevent possible consecutive immediate failures that lead to
           // excessive CPU consumption.
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               // Ignore.
           }
       }
   }
}

hasTasks()方法判断当前taskQueue是否有元素。
1、 如果taskQueue中有元素,执行 selectNow() 方法,最终执行selector.selectNow(),该方法会立即返回。

void selectNow() throws IOException {
   try {
       selector.selectNow();
   } finally {
       // restore wakup state if needed
       if (wakenUp.get()) {
           selector.wakeup();
       }
   }
}

2、 如果taskQueue没有元素,执行 select(oldWakenUp) 方法,代码如下:

private void select(boolean oldWakenUp) throws IOException {
   Selector selector = this.selector;
   try {
       int selectCnt = 0;
       long currentTimeNanos = System.nanoTime();
       long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);
       for (;;) {
           long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L;
           if (timeoutMillis <= 0) {
               if (selectCnt == 0) {
                   selector.selectNow();
                   selectCnt = 1;
               }
               break;
           }
           int selectedKeys = selector.select(timeoutMillis);
           selectCnt ++;
           if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {
               // - Selected something,
               // - waken up by user, or
               // - the task queue has a pending task.
               // - a scheduled task is ready for processing
               break;
           }
           if (Thread.interrupted()) {
               // Thread was interrupted so reset selected keys and break so we not run into a busy loop.
               // As this is most likely a bug in the handler of the user or it's client library we will
               // also log it.
               //
               // See https://github.com/netty/netty/issues/2426
               if (logger.isDebugEnabled()) {
                   logger.debug("Selector.select() returned prematurely because " +
                           "Thread.currentThread().interrupt() was called. Use " +
                           "NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop.");
               }
               selectCnt = 1;
               break;
           }
           long time = System.nanoTime();
           if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) {
               // timeoutMillis elapsed without anything selected.
               selectCnt = 1;
           } else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 &&
                   selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
               // The selector returned prematurely many times in a row.
               // Rebuild the selector to work around the problem.
               logger.warn(
                       "Selector.select() returned prematurely {} times in a row; rebuilding selector.",
                       selectCnt);
               rebuildSelector();
               selector = this.selector;
               // Select again to populate selectedKeys.
               selector.selectNow();
               selectCnt = 1;
               break;
           }
           currentTimeNanos = time;
       }
       if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS) {
           if (logger.isDebugEnabled()) {
               logger.debug("Selector.select() returned prematurely {} times in a row.", selectCnt - 1);
           }
       }
   } catch (CancelledKeyException e) {
       if (logger.isDebugEnabled()) {
           logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector - JDK bug?", e);
       }
       // Harmless exception - log anyway
   }
}

这个方法解决了Nio中臭名昭著的bug:selector的select方法导致cpu100%。
1、delayNanos(currentTimeNanos):计算延迟任务队列中第一个任务的到期执行时间(即最晚还能延迟多长时间执行),默认返回1s。每个SingleThreadEventExecutor都持有一个延迟执行任务的优先队列PriorityQueue,启动线程时,往队列中加入一个任务。

protected long delayNanos(long currentTimeNanos) {  
   ScheduledFutureTask<?> delayedTask = delayedTaskQueue.peek();  
   if (delayedTask == null) {  
       return SCHEDULE_PURGE_INTERVAL;  
   }  
   return delayedTask.delayNanos(currentTimeNanos);  
}  
//ScheduledFutureTask  
public long delayNanos(long currentTimeNanos) {  
   return Math.max(0, deadlineNanos() - (currentTimeNanos - START_TIME));  
}  
public long deadlineNanos() {  
   return deadlineNanos;  
}  

2、如果延迟任务队列中第一个任务的最晚还能延迟执行的时间小于500000纳秒,且selectCnt == 0(selectCnt 用来记录selector.select方法的执行次数和标识是否执行过selector.selectNow()),则执行selector.selectNow()方法并立即返回。
3、否则执行selector.select(timeoutMillis),这个方法已经在深入浅出NIO Socket分析过。
4、如果已经存在ready的selectionKey,或者selector被唤醒,或者taskQueue不为空,或则scheduledTaskQueue不为空,则退出循环。
5、如果 selectCnt 没达到阈值SELECTOR_AUTO_REBUILD_THRESHOLD(默认512),则继续进行for循环。其中 currentTimeNanos 在select操作之后会重新赋值当前时间,如果selector.select(timeoutMillis)行为真的阻塞了timeoutMillis,第二次的timeoutMillis肯定等于0,此时selectCnt 为1,所以会直接退出for循环。
6、如果触发了epool cpu100%的bug,会发生什么?
selector.select(timeoutMillis)操作会立即返回,不会阻塞timeoutMillis,导致 currentTimeNanos 几乎不变,这种情况下,会反复执行selector.select(timeoutMillis),变量selectCnt 会逐渐变大,当selectCnt 达到阈值,则执行rebuildSelector方法,进行selector重建,解决cpu占用100%的bug。

public void rebuildSelector() {  
       if (!inEventLoop()) {  
           execute(new Runnable() {  
               @Override  
               public void run() {  
                   rebuildSelector();  
               }  
           });  
           return;  
       }  
       final Selector oldSelector = selector;  
       final Selector newSelector;  
       if (oldSelector == null) {  
           return;  
       }  
       try {  
           newSelector = openSelector();  
       } catch (Exception e) {  
           logger.warn("Failed to create a new Selector.", e);  
           return;  
       }  
       // Register all channels to the new Selector.  
       int nChannels = 0;  
       for (;;) {  
           try {  
               for (SelectionKey key: oldSelector.keys()) {  
                   Object a = key.attachment();  
                   try {  
                       if (key.channel().keyFor(newSelector) != null) {  
                           continue;  
                       }  
                       int interestOps = key.interestOps();  
                       key.cancel();  
                       key.channel().register(newSelector, interestOps, a);  
                       nChannels ++;  
                   } catch (Exception e) {  
                       logger.warn("Failed to re-register a Channel to the new Selector.", e);  
                       if (a instanceof AbstractNioChannel) {  
                           AbstractNioChannel ch = (AbstractNioChannel) a;  
                           ch.unsafe().close(ch.unsafe().voidPromise());  
                       } else {  
                           @SuppressWarnings("unchecked")  
                           NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;  
                           invokeChannelUnregistered(task, key, e);  
                       }  
                   }  
               }  
           } catch (ConcurrentModificationException e) {  
               // Probably due to concurrent modification of the key set.  
               continue;  
           }  
           break;  
       }    
       selector = newSelector;  
       try {  
           // time to close the old selector as everything else is registered to the new one  
           oldSelector.close();  
       } catch (Throwable t) {  
           if (logger.isWarnEnabled()) {  
               logger.warn("Failed to close the old Selector.", t);  
           }  
       }    
       logger.info("Migrated " + nChannels + " channel(s) to the new Selector.");  
   }  

rebuildSelector过程:
1、通过方法openSelector创建一个新的selector。
2、将old selector的selectionKey执行cancel。
3、将old selector的channel重新注册到新的selector中。

对selector进行rebuild后,需要重新执行方法selectNow,检查是否有已ready的selectionKey。

方法selectNow()或select(oldWakenUp)返回后,执行方法processSelectedKeys和runAllTasks。
1、processSelectedKeys 用来处理有事件发生的selectkey,这里对优化过的方法processSelectedKeysOptimized进行分析:

private void processSelectedKeysOptimized(SelectionKey[] selectedKeys) {
   for (int i = 0;; i ++) {
       final SelectionKey k = selectedKeys[i];
       if (k == null) {
           break;
       }
       // null out entry in the array to allow to have it GC'ed once the Channel close
       // See https://github.com/netty/netty/issues/2363
       selectedKeys[i] = null;
       final Object a = k.attachment();
       if (a instanceof AbstractNioChannel) {
           processSelectedKey(k, (AbstractNioChannel) a);
       } else {
           @SuppressWarnings("unchecked")
           NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;
           processSelectedKey(k, task);
       }
       if (needsToSelectAgain) {
           // null out entries in the array to allow to have it GC'ed once the Channel close
           // See https://github.com/netty/netty/issues/2363
           for (;;) {
               i++;
               if (selectedKeys[i] == null) {
                   break;
               }
               selectedKeys[i] = null;
           }
           selectAgain();
           // Need to flip the optimized selectedKeys to get the right reference to the array
           // and reset the index to -1 which will then set to 0 on the for loop
           // to start over again.
           //
           // See https://github.com/netty/netty/issues/1523
           selectedKeys = this.selectedKeys.flip();
           i = -1;
       }
   }
}

在优化过的方法中,有事件发生的selectkey存放在数组selectedKeys中,通过遍历selectedKeys,处理每一个selectkey,具体处理过程,会在后续进行分析。

2、runAllTasks 处理非I/O任务。
如果 ioRatio 不为100时,方法runAllTasks的执行时间只能为ioTime * (100 - ioRatio) / ioRatio,其中ioTime 是方法processSelectedKeys的执行时间。

protected boolean runAllTasks(long timeoutNanos) {
   fetchFromScheduledTaskQueue();
   Runnable task = pollTask();
   if (task == null) {
       return false;
   }
   final long deadline = ScheduledFutureTask.nanoTime() + timeoutNanos;
   long runTasks = 0;
   long lastExecutionTime;
   for (;;) {
       try {
           task.run();
       } catch (Throwable t) {
           logger.warn("A task raised an exception.", t);
       }
       runTasks ++;
       // Check timeout every 64 tasks because nanoTime() is relatively expensive.
       // XXX: Hard-coded value - will make it configurable if it is really a problem.
       if ((runTasks & 0x3F) == 0) {
           lastExecutionTime = ScheduledFutureTask.nanoTime();
           if (lastExecutionTime >= deadline) {
               break;
           }
       }
       task = pollTask();
       if (task == null) {
           lastExecutionTime = ScheduledFutureTask.nanoTime();
           break;
       }
   }
   this.lastExecutionTime = lastExecutionTime;
   return true;
}

方法fetchFromScheduledTaskQueue把scheduledTaskQueue中已经超过延迟执行时间的任务移到taskQueue中等待被执行。

private void fetchFromScheduledTaskQueue() {
   if (hasScheduledTasks()) {
       long nanoTime = AbstractScheduledEventExecutor.nanoTime();
       for (;;) {
           Runnable scheduledTask = pollScheduledTask(nanoTime);
           if (scheduledTask == null) {
               break;
           }
           taskQueue.add(scheduledTask);
       }
   }
}

依次从taskQueue任务task执行,每执行64个任务,进行耗时检查,如果已执行时间超过预先设定的执行时间,则停止执行非IO任务,避免非IO任务太多,影响IO任务的执

Java读源码之Netty深入剖析----3.Netty服务端启动 Java读源码之Netty深入剖析----3.Netty服务端启动 分析服务端启动流程,包括服务端Channel的创建,初始化,以及注册到selector 3-1 服务端启动demo 3-2 服务端Channel的创建 3-3 服务端Channel的初始化 3-4 注册selector 3-5 服务端口的绑定 3-6 服务端启动总结   netty源码阅读之服务端启动   netty服务... 阅读详情

相关推荐

C++cgal库配置+VS2017

Cgal几何图形库在VS2017上的下载、安装与配置。想要一口气下载完所有安装配件的,可以去文章末尾的链接。httpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttps。

dsn3S的博客 1491

Netty实战专栏 | Java网络编程深入解析

大家好,我是Leo哥🫣🫣🫣,本次专栏学习Java并发以及netty应用的深度学习,netty提供了异步、事件驱动、非阻塞的网络编程模型,能够轻松处理高并发、高吞吐量的网络通信场景。是一个基于的高性能网络应用框架。但是在此之前我们需要对我们Java前置知识进行一些巩固和复习。那就是IO,Java网络编程,BIO,NIO,AIO相关知识点,前置知识是还是挺多,只有打好前面的基础我们才能更深入理解netty这个框架以及他的底层原理。对于IO相关的知识,大家可以看我之前写的这篇。

分享思想,留下痕迹。 1万+

【硬核指南/MI50 32G/Ubuntu】从零部署大模型:MI50显卡Ubuntu系统驱动安装与避坑全记录

本文详细记录了在Ubuntu系统上为AMD MI50显卡安装驱动并部署大模型的完整流程,包括硬件兼容性检查、BIOS关键设置、系统安装优化、ROCm驱动安装及常见问题解决方案。特别针对MI50显卡在X99平台上的特殊配置需求提供了实用技巧,帮助用户避免常见陷阱,提升大模型训练效率。

weixin_42520909的博客 811

Netty 专栏——Netty及其核心组件

https://pyc-ycy.blog.youkuaiyun.com/article/details/121875863 Netty 专栏——Netty及其核心组件 一、Netty概述 1、原生NIO的缺点 1)NIO的类库和API库繁杂,使用麻烦,需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等 2)需要具备其他额外的技能:Java多线程和Java网络编程,因为NIO涉及到Reactor模式 3)开发工作量和难度非常大:客户端断

yygr的博客 424

安路科技FPSoC开发实战:从芯片特性到边缘计算应用

本文深入解析安路科技FPSoC芯片在边缘计算领域的开发实战,重点介绍SALDRAGON系列芯片的异构计算架构优势,包括RISC-V/ARM处理器与FPGA的协同工作。通过工业控制和智能视觉应用案例,展示硬件加速实现与低功耗设计技巧,帮助开发者高效利用FPSoC进行边缘计算应用开发。

weixin_29248611的博客 378

飞腾X100芯片GPU状态查询

本文档对在linux系统下查看X100芯片GPU状态信息进行说明,可以帮助大家了解芯片的实时工作状态。

乌拉大喵喵 2819

Netty实战专栏 | JavaIO演进之路

大家好,我是Leo哥🫣🫣🫣,上一篇博客我们主要了解了Java网络编程的相关内容,通过对网络编程的一些了解,有助于我们学习接下来的知识点。在此之前,这一篇我想讲讲关于Java整个IO的演变历程,Java到底是怎样一步一步从基础IO操作到最后的AIO演变。好了,话不多说让我们开始吧😎😎😎。以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步

分享思想,留下痕迹。 1万+

信贷风控实战指南:Vintage分析表从数据建模到风险洞察

本文是一份信贷风控实战指南,详细阐述了Vintage分析从数据建模到风险洞察的全流程。文章深入解析了Vintage分析作为信贷资产“体检报告”的核心价值,并提供了从借据表与还款计划表设计、账龄计算、逾期口径判定到风险暴露计算与最终可视化透视的完整SQL实现方案,旨在帮助风控从业者构建精准的风险监控体系。

nft7creator的博客 321

Netty技术全解析:NioEventLoop类源码分析与技术详解

NioEventLoop是Netty框架中负责处理网络IO事件和异步任务的核心组件。它通过单线程事件循环、IO多路复用、任务队列和定时任务调度等机制,实现了高效、可靠的网络事件处理。在Netty的网络编程模型中,NioEventLoop扮演着至关重要的角色。

码到三十五 1314

如何创建 SAP ABAP CDS View 的 Association

所以本文我们虽然学习了如何创建 SAP CDS View 的 association,知道了 association 是用来在 CDS View 里将两张数据库表关联起来,但根本不知道怎么使用这个 association. 而且从 association 的写法来看,似乎和本教程之前介绍 inner join,left join 这些数据库表的连接操作没什么区别,都是根据两张表的 carrid 和 connid 字段相同进行的连接。只看到了我们在 CDS View 源代码实现里,放出来的四个字段。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 906

Backtrader官方中文文档:第四章Concepts基本概念

官方Concepts章节:https://backtrader.com/docu/concepts/

汇渊科技 2602

【Netty 专栏】Netty 源码分析之 accept 过程

点击上方“芋道源码”,选择“置顶公众号”技术文章第一时间送达!源码精品专栏 中文详细注释的开源项目Java 并发源码合集RocketMQ 源码合集Sharding-JDB...

芋道源码 428

Vue3 - 详细实现安装西瓜视频 xgplayer 插件详细配置及使用教程,利用西瓜视频播放器播放 mp4、flv、hls 格式视频文件及视频推流(直播或监控摄像头画面),支持移动端H5及PC网站!

vue3,nuxt3,西瓜视频,xgplayer,插件组件,xgplayer-hls,xgplayer-flv,xgplayer-mp4,播放视频点播和直播视频流,监控实时播放推流,倍速播放,在线flv在线推流地址,HLS播放,vue3西瓜播放器,vue如何使用西瓜视频插件做直播推流回流,视频点播,flv在线视频流播放,截图功能,自定义播放器样式,截屏,监控视频,vue3使用西瓜播放器播放flv、hls、mp4视频,截屏按钮,直播流,报错,黑屏,加载失败,苹果ios不兼容,重连,怎么改样式,很卡,详细教程,

🏆 前端领域优质创作者 1万+

Netty启动源码&NioEventLoop剖析&accept剖析&read剖析&write剖析

入口关键代码(1、注意main线程和nio线程的切换;​ 2、initAndRegister 对应 nio中 创建ServerSocketChannel 和 把ServerSocketChannel注册到selector上​ 3、doBind0 对应 nio中 bind监听端口)// 1. 执行初始化和注册 regFuture 会由 initAndRegister 设置其是否完成,从而回调 3.2 处代码= null) {

pscool的博客 1418

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

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

netty系列之源码分析

netty系列源码分析

qq_37436172的博客 1051

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java之深入剖析netty_Java读源码之Netty深入剖析 - IT

Netty概述官方:Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.特点:和Mina,Grizzly一样都是基于nio的通信框架,事件驱动,...

weixin_39540315的博客 433

Netty源码分析6:NioEventLoop

NioEventLoop基本介绍 在构建Netty服务时,首先需要创建一个NioEventLoopGroup,即如下代码: ··· NioEventLoopGroup boss = new NioEventLoopGroup(1); NioEventLoopGroup worker = new NioEventLoopGroup(); ··· 初始化时机:NioEventLoopGroup内部定义了一个EventExecutor[] children成员变量(NioEventLoop是EventExec

heng_zou的博客 510

NioEventLoop源码分析

前面几期带大家分析了Netty的服务端启动,客户端连接,客户端消息处理的流程,本期就来讲解Netty中一个极其重要的组件,事件循环器EventLoop。 NioEventLoopGroup分析 我们平常使用Netty的时候,一般都是用NioEventLoopGroup进行操作,所以我们从NioEventLoopGroup开始分析。首先来看一下NioEventLoopGroup的继承体系 从上图可以看出NioEventLoopGroup是一个线程池,所以有一个execute()方法,并且实现了Schedul

weixin_45271492的博客 1136

Netty全面解析

Netty全面解析

qq_45443475的博客 3341

Netty源码------NioEventLoop源码详解

Netty源码------NioEventLoop 目录 Netty源码------NioEventLoop 1、初识NioEventLoop 2、NioEventLoop创建 3、NioEventLoop启动 4、NioEventLoop执行过程 5、Netty 解决JDK 空轮询Bug 6、总结 1、初识NioEventLoop 1.1先来简单回顾一下Netty模型 Netty中的Channel系列类型,对应于经典Reactor模型中的client, 封装了用户的...

烟雨gps 1154

Netty专栏 (二)——— Netty的重要组件介绍与传输

  @author 鲁伟林 记录《Netty 实战》中各章节学习过程,写下一些自己的思考和总结,帮助使用Netty框架的开发技术人员们,能够有所得,避免踩坑。 本博客目录结构将严格按照书本《Netty 实战》,省略与Netty无关的内容,可能出现跳小章节。 本博客中涉及的完整代码: GitHub地址: https://github.com/thinkingfioa/netty-learning...

thinking_fioa的博客 1万+

Netty实战专栏 | NIO详解

大家好,我是Leo哥🫣🫣🫣,上一篇博客我们主要大致了解了一下Java中IO的演变历程,大体分为基础IO–>BIO–>NIO–>AIO这几个阶段,分部逐层递进。下面几个章节我们就要来聊聊这个变化。本节主要讨论关于NIO的知识。好了,话不多说让我们开始吧😎😎😎。以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。

分享思想,留下痕迹。 2万+
上一篇: 【消息队列 MQ 专栏】RabbitMQ
下一篇: 【RPC 专栏】深入理解 RPC 之传输篇
公众号-芋道源码
博客等级 码龄10年 1634粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值