嘿,同学,你要的 Java 内存模型 (JMM) 来了

面试官:说说什么是 Java 内存模型(JMM)? 本文禁止转载 1. 为什么要有内存模型? 1.1. 硬件内存架构 1.2. 缓存一致性问题 1.3. 处理器优化和指令重排序 2. 并发编程的问题 3. Java 内存模型 3.1. Java 运行时内存区域与硬件内存的关系 3.2. Java 线程与主内存的关系 3.3. 线程间通信 4. 有态度的总结 在面试中,面试官经常喜欢问:『说说什么是Java内存模型(JMM)?』 面试者内心狂喜,这题刚背过:『Java内存主要分为五大块:堆、方法区、虚拟机栈、本地方法栈、PC寄存器,ba. 阅读详情
  • 1、 计算机的硬件内存结构

  • 2、 Java 内存模型的背景和定义

  • 3、 Java 内存模型 3.1 主内存、工作内存的定义 3.2 内存的交互操作 3.3 JMM 缓存不一致问题

  • 4、 Java 内存模型的实现

在学习 Java 内存模型(JMM)前,我们先了解下计算机的硬件内存结构,因为 JMM 结构就是基于此演变而来的。

1、 计算机的硬件内存结构

在单核计算机中,计算机中的 CPU 计算速度是非常快的,但是与计算机中的其它硬件(如 IO、内存等)同 CPU 的速度比起来是相差甚远的,所以协调 CPU 和各个硬件之间的速度差异是非常重要的,要不然 CPU 就一直在等待,浪费资源。单核尚且如此,在多核中,这样的问题会更加的突出。硬件结构如下图所示:

我们先大概梳理下这个流程:当我们的计算机要执行某个任务或者计算某个数字时,主内存会首先从数据库中加载计算机计算所需要的数据,因为内存和 CPU 的速度相差较大,所以有必要在内存和 CPU 间引入缓存(根据实际的需要,可以引入多层缓存),主内存中的数据会先存放在 CPU 缓存中,当这些数据需要同 CPU 做交互时会加入到 CPU 寄存器中,最后被 CPU 使用。

事实上,在单核情况下,基于缓存的交互可以很好的解决 CPU 与其它硬件之间的速度匹配,但是在多核情况下,各个处理器都要遵循一定的协议来保障内存中的各个处理器的缓存和主内存中的数据一致性问题,这类协议通常被称为缓存一致性协议。

2、 Java 内存模型的背景和定义

我们在开发时会经常遇到这样的场景,我们开发完成的代码在我们自己的运行环境上表现良好,但是当我们把它放在其它硬件平台上时,就会出现各种各样的错误,这是因为在不同的硬件生产商和不同的操作系统下,内存的访问逻辑有一定的差异,结果就是当你的代码在某个系统环境下运行良好,并且线程安全,但是换了个系统就出现各种问题。

为了解决这个问题,Java 内存模型(JMM)的概念就被提出来了,它的出现可以屏蔽系统和硬件的差异,让一套代码在不同平台下能到达相同的访问结果,实现平台的一致性,使得 Java 程序能够一次编写,到处运行。

这样的描述的好像有点熟悉啊,这不是 JVM 的概念描述么,它们两者有什么区别啊?

JVM 与 JMM 间的区别?

实际上,JMM 是 Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式,JMM 定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本,本地内存是 JMM 的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。而 JVM 则是描述的是 Java 虚拟机内部及各个结构间的关系。

小伙伴这时可能会有疑问,既然 JMM 是定义线程和主内存之间的关系,那么它的出现是不是解决并发领域的问题啊?没错,我们先回顾一下并发领域中的关键问题。

并发领域中的关键问题?

  • 线程之间的通信

在编程中,线程之间的通信机制有两种,共享内存和消息传递。

在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信,典型的共享内存通信方式就是通过共享对象进行通信。

消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信,在 java 中典型的消息传递方式就是 wait()和 notify()。

  • 线程间的同步

同步是指程序用于控制不同线程之间操作发生相对顺序的机制。在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。

事实上,Java 内存模型(JMM)的并发采用的是共享内存模型。

下面,我们一起来学习 Java 内存模型

3、 Java 内存模型

我们先看一张 JMM 的控制模型作图

由此可见,Java 内存模型(JMM)同 CPU 缓存模型结构类似,是基于 CPU 缓存模型来建立的。

我们先梳理一下 JMM 的工作流程,以上图为例,我们假设有一台四核的计算机,cpu1 操作线程 A,cpu2 操作线程 B,cpu3 操作线程 C,当这三个线程都需要对主内存中的共享变量进行操作时,这三条线程分别会将主内存中的共享内存读入自己的工作内存,自己保存一份共享变量的副本供自己线程本身使用。

这时有的小伙伴可能会有以下疑问:

  • 主内存、工作内存的定义是什么?

  • 如何将主内存中的共享变量读入自己线程本身的工作内存?

  • 当其中的某一条线程修改了共享变量后,其余线程中的共享变量值是否变化,如果变化,线程间是怎么保持可见性的?

下面,我们针对这两个疑问一一解答。

3.1 主内存、工作内存的定义

  • 主内存

主内存主要存储的是 Java 实例对象,即所有线程创建的实例对象都存放在主内存中,不管该实例对象是成员变量还是方法中的本地变量(也称局部变量),当然也包括了共享的类信息、常量、静态变量。由于是共享数据区域,多条线程对同一个变量进行访问可能会发现线程安全问题。

  • 工作内存

工作内存主要存储当前方法的所有本地变量信息(工作内存中存储着主内存中的变量副本拷贝),即每个线程只能访问自己的工作内存,即线程中的本地变量对其它线程是不可见的,就算是两个线程执行的是同一段代码,它们也会各自在自己的工作内存中创建属于当前线程的本地变量,当然也包括了字节码行号指示器、相关 Native 方法的信息。注意由于工作内存是每个线程的私有数据,线程间无法相互访问工作内存,因此存储在工作内存的数据不存在线程安全问题。

NOTE:这里的主内存、工作内存与 Java 内存区域中的 Java 堆、栈、方法区不是同一层次的内存划分,这两者基本上没有关系。

搞清楚主内存和工作内存后,下一步就需要学习主内存与工作内存的数据交互操作的方式。

3.2 内存的交互操作

主内存与工作内存的交互操作有 8 种,虚拟机必须保证每一个操作都是原子的,这八种操作分别是:

  • Lock(锁定)

作用于主内存的变量,把一个变量标识为一条线程独占状态。

  • unlock(解锁)

作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

  • read(读取)

作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的 load 动作使用

  • load(载入)

作用于工作内存的变量,它把 read 操作从主存中变量放入工作内存中

  • use(使用)

作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令

  • assign(赋值)

作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中

  • store(存储)

作用于工作内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的 write 使用

  • write(写入)

作用于主内存中的变量,它把 store 操作从工作内存中得到的变量的值放入主内存的变量中

单看这八种类型的原子操作可能有点抽象,我们画一个操作流程图仔细梳理下。

操作流程图:

从图中可以看出,如果要把一个变量从内存中复制到工作内存中,就需要顺序的执行 read 和 load 操作,如果把变量从工作内存同步到主内存中,就需要执行 store 和 write 操作。

NOTE: Java 内存模型只要求上述操作必须按顺序执行,却没要求是连续执行。

我们以两个线程为例梳理下操作流程:

假设存在两个线程 A 和 B,如果线程 A 要与线程 B 要通信的话,首先,线程 A 把本地内存 A 中更新过的共享变量刷新到主内存中去;然后,线程 B 到主内存中读取线程 A 之前已经更新过的共享变量。

敏锐的小伙伴可能会发现,如果多个线程同时读取修改同一个共享变量,这种情况可能会导致每个线程中的本地内存中缓存变量一致的问题,这个时候该怎么解决呢?

3.3 JMM 缓存不一致问题

解决 JMM 中的本地内存变量的缓存不一致问题有两种解决方案,分别是总线加锁和MESI缓存一致性协议。

总线加锁

总线加锁是 CPU 从主内存读取数据到本地内存时,会先在总线对这个数据加锁,这样其它 CPU 就没法去读或者去写这个数据,直到这个 CPU 使用完数据释放锁后,,其它的 CPU 才能读取该数据。

总线加锁虽然能保证数据一致,但是它却严重降低了系统性能,因为当一个线程多总线加锁后,其它线程都只能等待,将原有的并行操作转成了串行操作。

通常情况下,我们不采用这种方法,而是使用性能较高的缓存一致性协议。

MESI 缓存一致性协议

MESI 缓存一致性协议是多个 CPU 从主内存读取同一个数据到各自的高速缓存中,当其中的某个 CPU 修改了缓存里的数据,该数据会马上同步回主内存,其它 CPU 通过总线嗅探机制可以感知到数据的变化从而将自己缓存里的数据失效。

在并发编程中,如果多个线程对同一个共享变量进行操作是,我们通常会在变量名称前加上关键在volatile,因为它可以保证线程对变量的修改的可见性,保证可见性的基础是多个线程都会监听总线。即当一个线程修改了共享变量后,该变量会立马同步到主内存,其余线程监听到数据变化后会使得自己缓存的原数据失效,并触发read操作读取新修改的变量的值。进而保证了多个线程的数据一致性。事实上,volatile的工作原理就是依赖于 MESI 缓存一致性协议实现的。

4、 Java 内存模型的实现

在 Java 多线程中,Java 提供了一系列与并发处理相关的关键字,比如volatile、synchronized、final、concurren包等。其实这些就是 Java 内存模型封装了底层的实现后提供给程序员使用的一些关键字

事实上,Java 内存模型的本质是围绕着 Java 并发过程中的如何处理原子性、可见性和顺序性这三个特征来设计的,这三大特性可以直接使用 Java 中提供的关键字实现,它们也是面试中经常被问到的题目。

  • 原子性

原子性的定义是一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。

JMM 保证的原子性变量操作包括 read、load、assign、use、store、write

NOTE:基本类型数据的访问大都是原子操作,long 和 double 类型的变量是 64 位,但是在 32 位 JVM 中,32 位的 JVM 会将 64 位数据的读写操作分为 2 次 32 位的读写操作来进行,这就导致了 long、double 类型的变量在 32 位虚拟机中是非原子操作,数据有可能会被破坏,也就意味着多个线程在并发访问的时候是线程非安全的。

对于非原子操作的基本类型,可以使用 synchronized 来保证方法和代码块内的操作是原子性的。

synchronized (this) {  a=1;   b=2;}

复制代码

如一个线程观察另外一个线程执行上面的代码,只能看到 a、b 都被赋值成功结果,或者 a、b 都尚未被赋值的结果。

  • 可见性

Java 内存模型是通过在变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值的这种依赖主内存作为传递媒介的方式来实现的。

Java 中的 volatile 关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用 volatile 来保证多线程操作时变量的可见性。

除了 volatile,Java 中的 synchronized 和 final 两个关键字也可以实现可见性。只不过实现方式不同,这里不再展开了。

  • 有序性

在 Java 中,可以使用 synchronized 和 volatile 来保证多线程之间操作的有序性。实现方式有所区别:

volatile 关键字会禁止指令重排。synchronized 关键字保证同一时刻只允许一条线程操作。

好了,这里简单的介绍完了 Java 并发编程中解决原子性、可见性以及有序性可以使用的关键字。读者可能发现了,好像 synchronized 关键字是万 能的,他可以同时满足以上三种特性,这其实也是很多人滥用 synchronized 的原因。

但是 synchronized 是比较影响性能的,虽然编译器提供了很多锁优化技术,但是也不建议过度使用。

参考文献

[1]https://www.jianshu.com/p/8a58d8335270

[2]https://blog.youkuaiyun.com/javazejian/article/details/72772461

[3]https://blog.youkuaiyun.com/zjcjava/article/details/78406330

[4]https://segmentfault.com/a/1190000016085105

GD32F4系列定时器正交译码器实战:用TIMER1读取旋转编码器信号(附完整代码) 本文详细介绍了GD32F4系列定时器正交译码器的实战应用,重点讲解如何使用TIMER1模块高效读取旋转编码器信号。内容涵盖硬件连接、定时器配置、方向判断与速度计算等关键环节,并提供了完整的代码实现和优化建议,帮助开发者快速掌握GD32微控制器在工业控制和消费电子领域的编码器接口设计。 阅读详情

相关推荐

Android系统编译之Communication error with Jack server (35), try ‘jack-diagnose‘ or see Jack server log

jack server failed场景个人分析网上分析分析1分析2原因1:权限问题原因2:端口占用原因3:删除 TLSv1, TLSv1.1测试结论解决方案说明相关链接 场景 在进行Android系统开发时,在liunx编译时发生问题,描述如下: ninja: build stopped: subcommand failed. build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed make: *** [ninja_wrapper

weixin_43194854的博客 2401

Jmeter教程(一) - 入门

一、下载 登录官网Jmeter下载,得到压缩包jmeter-5.0.tgz,下载地址:http://jmeter.apache.org/download_jmeter.cgi。 二、安装 将下载得到的压缩包解压即可,这里我解压到自己电脑的路径为E:\Mysoftware\apache-jmeter-5.0。 三、运行 点击bin目录下的jmeter.bat即可启动Jmeter。 启动后可以看到...

淡淡的说非 34万+

Frida+Objection保姆级教程:从环境搭建到实战Hook(含Wallbreaker插件使用)

本文提供了一份从零开始的Frida与Objection移动安全动态分析实战指南。详细讲解了Python环境配置、Frida-Server部署、Objection核心命令使用以及Wallbreaker插件安装与应用。通过实战案例演示如何Hook网络请求(如HttpURLConnection和OkHttp3),帮助安全研究人员快速掌握应用运行时行为分析与漏洞挖掘技能。

weixin_28318011的博客 100

嘿,同学,你要的 Java 内存模型 (JMM) 来了-volatile

我们在开发时会经常遇到这样的场景,我们开发完成的代码在我们自己的运行环境上表现良好,但是当我们把它放在其它硬件平台上时,就会出现各种各样的错误,这是因为在不同的硬件生产商和不同的操作系统下,内存的访问逻辑有一定的差异,结果就是当你的代码在某个系统环境下运行良好,并且线程安全,但是换了个系统就出现各种问题。为了解决这个问题,Java 内存模型(JMM)的概念就被提出来了,它的出现可以屏蔽系统和硬件的差异,让一套代码在不同平台下能到达相同的访问结果,实现平台的一致性,使得 Java 程序能够。

没有伞的孩子必须努力奔跑!—小林 145

ai获客系统功能代码

AI 获客系统是一个复杂的体系,以下为你提供一个简化的 Python 示例,聚焦于客户行为分析与销售线索筛选功能,模拟实现从多渠道收集数据后的初步处理流程。假设已有从官网、线上商城等渠道收集到的客户数据,以字典列表形式存储,每个字典包含客户基本信息及购买行为数据。通过分析客户购买频率与金额,筛选出高价值销售线索。python上述代码仅为基础示例,实际 AI 获客系统还涉及更复杂的数据采集、清洗、存储,以及运用机器学习算法进行深度客户洞察等功能。

weixin_ggwwsscc的博客 892

ICC 实战解析——CTS 时钟树综合中的关键设置与优化策略

本文深入解析ICC工具中CTS时钟树综合的关键设置与优化策略,涵盖时钟树异常引脚设置、目标参数配置、非默认布线规则(NDR)等核心技术。通过实战案例展示如何有效控制时钟偏差、优化信号完整性,并平衡功耗与面积,为芯片物理设计提供专业指导。

weixin_30872577的博客 324

Java 内存模型(JMM)探寻原理,深度讲解

网上有很多关于 Java 内存模型的文章,在《深入理解Java虚拟机》和《Java并发编程的艺术》等书中也都有关于这个知识点的介绍。但是,很多人读完之后还是搞不清楚,甚至有的人说自己更懵了。本文,就来整体的介绍一下 Java 内存模型,目的很简单,让你读完本文以后,就知道到底Java 内存模型是什么,为什么要有 Java 内存模型,Java 内存模型解决了什么问题等。

流华追梦的专栏 2430

S7-200SMART系列全套接线说明

SMART200接线方法,输入,输出,模拟量,面板,扩展糟等,并且详细说明接线原理。

文都龙哥 1万+

【JUC-JMM】Java Memory Model Java内存模型

JMM规定,任何线程不能直接操作主内存中的变量,应该先将主内存的变量复制一份到本地独立栈空间内,然后进行操作,操作完之后,将变量写回主内存,线程B再读取主存中的值就是最新的了。带着这个问题,学过计算机组成原理的同学应该知道,CPU中寄存器的访问速度很快,内存的访问速度相较来说,比较慢,为了协调CPU中寄存器与内存的访问速度差异,设计了。那么,我们不禁思索,Java内存模型有什么用,是用来做什么的呢?有了缓存之后,我们尽可能操作缓存中的数据,接下来问题来了,如果缓存中的数据被修改了,会造成缓存与内存中数据。

星光不问赶路人的博客 1184

华为海思:大小海思的双轮驱动战略分析

大海思的定位清晰明确,即专注于为华为内部提供高性能、高集成度的芯片解决方案,以支持华为终端、服务器等业务的快速发展。小海思的产品线广泛,涵盖了广域物联、短距物联、手机穿戴、显示交互、智慧视觉、智慧媒体、MCU、模拟以及光模块等多个领域。通过提供多样化的芯片解决方案,小海思旨在满足外部客户的不同需求,拓展华为海思在芯片市场的份额和影响力。大海思的产品布局主要围绕华为的内部需求展开。在智能手机应用处理器方面,大海思的麒麟系列芯片已经成为华为手机的标志性产品,以其出色的性能和能效比赢得了市场的广泛认可。

dream it possible 2922

采用了fluent模拟了平壁面结霜过程。udf,很经典,可以试试。

利用该模型作为FLUENT中的源项,模拟了在局部冷却下冷表面上的霜形成,以预测霜的形态、温度分布和霜的重量,结果与实验结果吻合良好。结果显示,霜首先围绕冷却块形成,然后逐渐向其他方向扩展,冷却块上方的霜密度最大。随着时间的推移,平均霜厚度逐渐增加,生长速率减慢,而平均霜密度随增长速率变快而增加。相变传递微观过程与机理、蒸发及冷凝换热、强化传热、高效传热管、热泵、制冷、节水节能新技术、电子元器件冷却、余热回收及梯级利用等。udf,很经典,可以试试。工程热物理、空调、热能、低温制冷、化工、物理等。

qq_15963745的博客 921

java内存模型(JMM)详解

转载于: 面试官:说说什么是Java内存模型?为什么要有内存模型? 要想回答这个问题,我们需要先弄懂传统计算机硬件内存架构。好了,要开始画图了 硬件内存架构图 含有一二三级架构的内存架构图 去过机房的同学都知道,一般在大型服务器上会配置多个CPU,每个CPU还会有多个核,这就意味着多个CPU或者多个核可以同时(并发)工作。如果使用 起了一个多线程的任务,很有可能每个 都会跑一个线程,那么你的任务在某一刻就是真正并发执行了。也就是 。是 内部集成的,在寄存器上执行操作的效率要比在主存上高出几个数量级在中

thlzjfefe的博客 1356

ICC2:平行打孔create_pg_stapling_vias

power rail(follow pin)不总是metal1一成不变的,当需要使用metal2做power rail,而standard cell的pg pin仍然是metal1时就需要平行打孔,从metal2到metal1。 以往都是用create_pg_vias -allow_parallel_objects来做,但这样有两个弊端,一是需要抓出所有的via12(包括standard cell内部的和出pin绕线产生的),添加routing blockage,防止create pg via的时候产生d

m0_61544122的博客 2258

一文带你深入了解JMM(Java内存模型)

synchronized的特点获得同步锁;清空工作内存;从主内存拷贝对象副本到工作内存;执行代码(计算或者输出等);刷新主内存数据;释放同步锁。所以,synchronized既保证了多线程的并发有序性和原子性,又保证了多线程的内存可见性。有序性和原子性都是通过同一时刻只有一个线程可以进入锁住的代码保证的(不被其他线程中断,避免了部分执行)。volatile是第二种Java多线程同步的手段。一个被volatile修饰的变量,JMM会确保所有线程看到的是一致的变量值。

xjx666666的博客 886

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

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

『JVM』什么是Java内存模型(JMM)?

Java内存模型(JMM)的相关知识,涉及到数据共享、volatile等面试常问的知识点。

HBBBOY的博客 743

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

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

彻底理解Java内存模型,它为什么会引发线程安全问题【吐血总结】

近日,有热心市民就 "Java内存模型 " 提出质疑: 线程是否会把所有需要操作的数据全加载到内存

成都彭于晏 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java内存模型——JMM

什么是Java内存模型? JMM((JavaMemoryModel)即为Java内存模型,JVM(Java Virtual Machine)是Java虚拟机,两者不能混为一谈。 下图为JMM模型图   其流程简单来说,就是主内存中的变量先写入到工作内存中,接着交给线程去进行运算,运算后工作内存中的变量副本值发生改变,然后再重新写入到主内存中。 其交互操作如下所示: lock (锁定):...

夜吟清风的博客 301

【面经——Java内存模型(JMM)】讲故事一样讲述JMM

对于java内存模型,我们需要了解的无非是几个问题:什么是java内存模型?为什么要有java内存模型?该怎么使用这个java内存模型?使用的时候它又会产生什么问题?能否解决,该如何解决呢? 下面,我将从它的出现的原因开始讲述上面几个问题。 为什么要有java内存模型及java内存模型是什么? java内存模型,首先它是一个模型,并不是真是存在的。它从java的层面定义了主存,工作内存的抽象概念,而它的底层对应着cpu寄存器、缓存、硬件内存、cpu指令优化等; 下图就是java内存模型,可以看到,里面有ja

weixin_44836233的博客 504

从底层吃透java内存模型(JMM)、volatile、CAS

前言 随着计算机的飞速发展,cpu从单核到四核,八核。在2020年中国网民数预计将达到11亿人。这些数据都意味着,作为一名java程序员,必须要掌握多线程开发,谈及多线程,绕不开的是对JMM(Java 内存模型)。那么什么是JMM?什么是可见性、原子性、有序性?如何解决?本文将从CPU的缓存开始谈起,深度解剖JMM底层原理。 CPU高速缓存(cache) 学过操作系统的同学都应该知道CPU缓存。那么为什么要弄这么一个CPU缓存呢?这是因为缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为

疯狂一世 897

并发编程 — 内存模型 JMM

Java 内存模型之JMM

搬运Gong 489

JMM Java内存模型

JMM规定了线程的工作内存和主内存之间的交互关系,以及线程之间的可见性和程序的执行顺序。一方面,要为程序员提供足够强的内存可见性保证;另一方面,对编译器和处理器的限制要尽可能地放松。JM...

luoxn28的专栏 278

【面试】说说什么是Java内存模型(JMM)?

由于CPU 和主内存间存在数量级的速率差,想到了引入了多级高速缓存的传统硬件内存架构来解决,多级高速缓存作为 CPU 和主内间的缓冲提升了整体性能。解决了速率差的问题,却又带来了缓存一致性问题。数据同时存在于高速缓存和主内存中,如果不加以规范势必造成灾难,因此在传统机器上又抽象出了内存模型。Java 语言在遵循内存模型的基础上推出了 JMM 规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。

DreamSun的博客 1030

深入理解Java内存模型JMM

目录 一:JMM基础与happens-before 并发编程模型的分类重排序处理器重排序与内存屏障指令happens-before 二:重排序与JMM的as-if-serial 数据依赖性as-if-serial语义程序顺序规则重排序对多线程的影响 三:顺序一致性内存模型与JMM 数据竞争与顺序一致性保证顺序一致性内存模型同步程序的顺序一致性效果未同步程序的执行特性 该系列博文会告诉你如何全面深入地学习Java并发技术,从Java多线程基础,再到并发编程的基础知识,从Java并发包的入门和实战,再

通往IT大道的专栏 144
上一篇: 从数据到价值,DataOps 精益数据运营概述
下一篇: Kafka 核心知识点灵魂 16 问
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值