JMM指令重排

学了 JMM 指令重排序,让我明白该如何写单例模式了 JMM 是什么? JVM 是 Java Memory Model 的缩写, Java 内存模型来屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下能够达到一致的内存访问效果。 重排序 在许多情况下,访问程序变量(对象实例字段、类静态字段和数组元素)的执行顺序可能与程序指定的顺序不同。编译器可以以优化的名义随意调整指令的顺序。在某些情况下,处理器可能会乱序执行指令。数据可以按照不同于程序指定的顺序在寄存器、处理器缓存和主存储器之间移动。 产生重排序? 下面是一个简单的例子,我运行的 阅读详情

指令重排

对于编译器的编写者来说,Java内存模型(JMM)主要是由禁止指令重排的规则所组成的,其中包括了字段(包括数组中的元素)的存取指令和监视器(锁)的控制指令。

Volatile与监视器

JMM中关于volatile和监视器主要的规则可以被看作一个矩阵。这个矩阵的单元格表示在一些特定的后续关联指令的情况下,指令不能被重排。下面的表格并不是JMM规范包含的,而是一个用来观察JMM模型对编译器和运行系统造成的主要影响的工具。

能否重排第二个操作
第一个操作Normal Load
Normal Store
Volatile load
MonitorEnter
Volatile store
MonitorExit
Normal Load
Normal Store
  No
Volatile load
MonitorEnter
NoNoNo
Volatile store
MonitorExit
 NoNo
关于上面这个表格一些术语的说明:

  • Normal Load指令包括:对非volatile字段的读取,getfield,getstatic和array load;
  • Normal Store指令包括:对非volatile字段的存储,putfield,putstatic和array store;
  • Volatile load指令包括:对多线程环境的volatile变量的读取,getfield,getstatic;
  • Volatile store指令包括:对多线程环境的volatile变量的存储,putfield,putstatic;
  • MonitorEnters指令(包括进入同步块synchronized方法)是用于多线程环境的锁对象;
  • MonitorExits指令(包括离开同步块synchronized方法)是用于多线程环境的锁对象。

在JMM中,Normal Load指令与Normal store指令的规则是一致的,类似的还有Volatile load指令与MonitorEnter指令,以及Volatile store指令与MonitorExit指令,因此这几对指令的单元格在上面表格里都合并在了一起(但是在后面部分的表格中,会在有需要的时候展开)。在这个小节中,我们仅仅考虑那些被当作原子单元的可读可写的变量,也就是说那些没有位域(bit fields),非对齐访问(unaligned accesses)或者超过平台最大字长(word size)的访问。

任意数量的指令操作都可被表示成这个表格中的第一个操作或者第二个操作。例如在单元格[Normal Store, Volatile Store]中,有一个No,就表示任何非volatile字段的store指令操作不能与后面任何一个Volatile store指令重排, 如果出现任何这样的重排会使多线程程序的运行发生变化。

JSR-133规范规定上述关于volatile和监视器的规则仅仅适用于可能会被多线程访问的变量或对象。因此,如果一个编译器可以最终证明(往往是需要很大的努力)一个锁只被单线程访问,那么这个锁就可以被去除。与之类似的,一个volatile变量只被单线程访问也可以被当作是普通的变量。还有进一步更细粒度的分析与优化,例如:那些被证明在一段时间内对多线程不可访问的字段。

在上表中,空白的单元格代表在不违反Java的基本语义下的重排是允许的(详细可参考JLS中的说明)。例如,即使上表中没有说明,但是也不能对同一个内存地址上的load指令和之后紧跟着的store指令进行重排。但是你可以对两个不同的内存地址上的load和store指令进行重排,而且往往在很多编译器转换和优化中会这么做。这其中就包括了一些往往不认为是指令重排的例子,例如:重用一个基于已经加载的字段的计算后的值而不是像一次指令重排那样去重新加载并且重新计算。然而,JMM规范允许编译器经过一些转换后消除这些可以避免的依赖,使其可以支持指令重排。

在任何的情况下,即使是程序员错误的使用了同步读取,指令重排的结果也必须达到最基本的Java安全要求。所有的显式字段都必须不是被设定成0或null这样的预构造值,就是被其他线程设值。这通常必须把所有存储在堆内存里的对象在其被构造函数使用前进行归零操作,并且从来不对归零store指令进行重排。一种比较好的方式是在垃圾回收中对回收的内存进行归零操作。可以参考JSR-133规范中其他情况下的一些关于安全保证的规则。

这里描述的规则和属性都是适用于读取Java环境中的字段。在实际的应用中,这些都可能会另外与读取内部的一些记账字段和数据交互,例如对象头,GC表和动态生成的代码。

Final 字段

Final字段的load和store指令相对于有锁的或者volatile字段来说,就跟Normal load和Normal store的存取是一样的,但是需要加入两条附加的指令重排规则:

  1. 如果在构造函数中有一条final字段的store指令,同时这个字段是一个引用,那么它将不能与构造函数外后续可以让持有这个final字段的对象被其他线程访问的指令重排。例如:你不能重排下列语句:
    x.finalField = v;
    ... ;
    sharedRef = x;
    

    这条规则会在下列情况下生效,例如当你内联一个构造函数时,正如“…”的部分表示这个构造函数的逻辑边界那样。你不能把这个构造函数中的对于这个final字段的store指令移动到构造函数外的一条store指令后面,因为这可能会使这个对象对其他线程可见。(正如你将在下面看到的,这样的操作可能还需要声明一个内存屏障)。类似的,你不能把下面的前两条指令与第三条指令进行重排:

    x.afield = 1; x.finalField = v; ... ; sharedRef = x;
  2. 一个final字段的初始化load指令不能与包含该字段的对象的初始化load指令进行重排。在下面这种情况下,这条规则就会生效:x = shareRef; … ; i = x.finalField;
    由于这两条指令是依赖的,编译器将不会对这样的指令进行重排。但是,这条规则会对某些处理器有影响。

上述规则,要求对于带有final字段的对象的load本身是synchronized,volatile,final或者来自类似的load指令,从而确保java程序员对与final字段的正确使用,并最终使构造函数中初始化的store指令和构造函数外的store指令排序。

—————————————————————————————————————————–

Reorderings

For a compiler writer, the JMM mainly consists of rules disallowing reorderings of certain instructions that access fields (where “fields” include array elements) as well as monitors (locks).

Volatiles and Monitors

The main JMM rules for volatiles and monitors can be viewed as a matrix with cells indicating that you cannot reorder instructions associated with particular sequences of bytecodes. This table is not itself the JMM specification; it is just a useful way of viewing its main consequences for compilers and runtime systems.

Can Reorder2nd operation
1st operationNormal Load
Normal Store
Volatile load
MonitorEnter
Volatile store
MonitorExit
Normal Load
Normal Store
  No
Volatile load
MonitorEnter
NoNoNo
Volatile store
MonitorExit
 NoNo

Where:

  • Normal Loads are getfield, getstatic, array load of non-volatile fields.
  • Normal Stores are putfield, putstatic, array store of non-volatile fields
  • Volatile Loads are getfield, getstatic of volatile fields that are accessible by multiple threads
  • Volatile Stores are putfield, putstatic of volatile fields that are accessible by multiple threads
  • MonitorEnters (including entry to synchronized methods) are for lock objects accessible by multiple threads.
  • MonitorExits (including exit from synchronized methods) are for lock objects accessible by multiple threads.

The cells for Normal Loads are the same as for Normal Stores, those for Volatile Loads are the same as MonitorEnter, and those for Volatile Stores are same as MonitorExit, so they are collapsed together here (but are expanded out as needed in subsequent tables). We consider here only variables that are readable and writable as an atomic unit — that is, no bit fields, unaligned accesses, or accesses larger than word sizes available on a platform.

Any number of other operations might be present between the indicated 1st and 2nd operations in the table. So, for example, the “No” in cell [Normal Store, Volatile Store] says that a non-volatile store cannot be reordered with ANY subsequent volatile store; at least any that can make a difference in multithreaded program semantics.

The JSR-133 specification is worded such that the rules for both volatiles and monitors apply only to those that may be accessed by multiple threads. If a compiler can somehow (usually only with great effort) prove that a lock is only accessible from a single thread, it may be eliminated. Similarly, a volatile field provably accessible from only a single thread acts as a normal field. More fine-grained analyses and optimizations are also possible, for example, those relying on provable inaccessibility from multiple threads only during certain intervals.

Blank cells in the table mean that the reordering is allowed if the accesses aren’t otherwise dependent with respect to basic Java semantics (as specified in theJLS). For example even though the table doesn’t say so, you can’t reorder a load with a subsequent store to the same location. But you can reorder a load and store to two distinct locations, and may wish to do so in the course of various compiler transformations and optimizations. This includes cases that aren’t usually thought of as reorderings; for example reusing a computed value based on a loaded field rather than reloading and recomputing the value acts as a reordering. However, the JMM spec permits transformations that eliminate avoidable dependencies, and in turn allow reorderings.

In all cases, permitted reorderings must maintain minimal Java safety properties even when accesses are incorrectly synchronized by programmers: All observed field values must be either the default zero/null “pre-construction” values, or those written by some thread. This usually entails zeroing all heap memory holding objects before it is used in constructors and never reordering other loads with the zeroing stores. A good way to do this is to zero out reclaimed memory within the garbage collector. See the JSR-133 spec for rules dealing with other corner cases surrounding safety guarantees.

The rules and properties described here are for accesses to Java-level fields. In practice, these will additionally interact with accesses to internal bookkeeping fields and data, for example object headers, GC tables, and dynamically generated code.

Final Fields

Loads and Stores of final fields act as “normal” accesses with respect to locks and volatiles, but impose two additional reordering rules:

  1. A store of a final field (inside a constructor) and, if the field is a reference, any store that this final can reference, cannot be reordered with a subsequent store (outside that constructor) of the reference to the object holding that field into a variable accessible to other threads. For example, you cannot reorder
    x.finalField = v; ... ; sharedRef = x;
    This comes into play for example when inlining constructors, where “...” spans the logical end of the constructor. You cannot move stores of finals within constructors down below a store outside of the constructor that might make the object visible to other threads. (As seen below, this may also require issuing a barrier). Similarly, you cannot reorder either of the first two with the third assignment in:
    v.afield = 1; x.finalField = v; ... ; sharedRef = x;
  2. The initial load (i.e., the very first encounter by a thread) of a final field cannot be reordered with the initial load of the reference to the object containing the final field. This comes into play in:
    x = sharedRef; ... ; i = x.finalField;
    A compiler would never reorder these since they are dependent, but there can be consequences of this rule on some processors.

These rules imply that reliable use of final fields by Java programmers requires that the load of a shared reference to an object with a final field itself be synchronized, volatile, or final, or derived from such a load, thus ultimately ordering the initializing stores in constructors with subsequent uses outside constructors.


C语言试题四之计算并输出3到n之间所有素数的平方根之和 1、题目 请编写函数function,它的功能是:计算并输出3到n之间所有素数的平方根之和 例子:若我们main函数从键盘给n输入5之后,我们需要输出结果为3.968119 输入值n的要求:正整数n, 要求小于100。 2、部分函数说明 C 库函数 double sqrt(double x) 返回 x 的平方根 3、源代码实现 #include <stdio.h> #... 阅读详情

相关推荐

SAP ABAP实战:如何用CVI_EI_INBOUND_MAIN批量更新BP邮箱(附完整代码)

本文深入解析了SAP ABAP中CVI_EI_INBOUND_MAIN函数在业务伙伴(BP)邮箱地址批量维护场景下的应用。通过详细讲解数据结构构建、关键参数(如任务参数'5')配置及完整代码示例,为开发者提供了一套高效、稳定的批量更新解决方案,并分享了性能优化与错误处理的最佳实践。

weixin_29228781的博客 76

6.Java内存模型(JMM)-指令重排

       在执行程序时,为了提高性能,处理器和编译器常常会对指令进行重排序;当然不能随意重排序,指令重排需要满足以下两个条件:       1.在单线程环境下不能改变程序运行的结果;       2.存在数据依赖关系的不允许重排序;       其实这两点可以归结于一点:happens-before规定的顺序不能改变,其他的JMM允许任意的排序;      从硬件架构上来说,指令重排序是指CP...

写后端的小学生 1662

STM32 SAI接口实战:用CubeMX快速配置多通道音频采集(附DMA优化技巧)

本文详细介绍了如何使用STM32的SAI接口通过CubeMX快速配置多通道音频采集系统,并提供了DMA双缓冲优化技巧。内容涵盖TDM模式配置、时钟同步、DMA优化及常见问题排查,帮助开发者高效实现高速数据采集应用。

weixin_42549037的博客 225

JMM 指令重排

指令重排 对于编译器的编写者来说,Java内存模型(JMM)主要是由禁止指令重排的规则所组成的,其中包括了字段(包括数组中的元素)的存取指令和监视器(锁)的控制指令。 Volatile与监视器 JMM中关于volatile和监视器主要的规则可以被看作一个矩阵。这个矩阵的单元格表示在一些特定的后续关联指令的情况下,指令不能被重排。下面的表格并不是JMM规范包含的,而是一个用来观察J

Code-lover's Learning Notes 1844

图像特征(一)——颜色特征(颜色直方图,颜色矩,颜色集,颜色聚合向量和颜色相关图)

本文主要是为了更好地理解图像特征,理解各方法的原理。转载请注明出处https://mp.youkuaiyun.com/console/editor/html/105090183 图像模式识别的一般步骤为:输入图像--图像预处理--特征提取--特征选择--图像分类--输出结果。 图像特征主要有:颜色特征、形状特征、纹理特征和空间关系特征。 本文主要介绍颜色特征,并给出matlab上实现的demo。 颜...

gloria_iris的博客 3万+

【超详细】C#的单例模式

本文详细介绍了C#中的单例设计模式,包括两种实现方式:普通类泛型单例(Singleton<T>)和基于MonoBehaviour的组件单例(MonoSingleton<T>)。单例模式通过私有构造、静态私有实例和公共访问入口确保全局唯一实例,具有节省资源、保证数据一致性等优势。文章分别阐述了两者的核心原理、代码实现、使用场景及注意事项,并提供了日志管理器和音效管理器的具体应用示例。特别强调了多线程安全、初始化时机和避免过度使用等重要原则,为Unity开发中合理运用单例模式提供了全面指导。

grapefruit_lyy的博客 1533

JMM 指令重排序

一、指令为什么要重排序? 在计算机系统中,指令为了更快的完成结果,会根据逻辑关系、指令大小进行重排序,以达到超流水线的效果,但在代码执行完后,保证结果输出是一致...

M_Andrain的博客 202

数据资产入表——解读100页数据资产入表解读与分析【附全文阅读】

本文档《数据资产入表:解读与分析》面向企业财务、数据管理、法务合规及高管等核心岗位,系统解析数据资产入表全流程。以"政策-实操-价值"为主线,首先解读入表政策要求,明确会计处理规范;其次详细拆解数据盘点、治理、确权、评估等实操步骤,提供行业案例参考;最后分析入表难点及后续运营策略,为企业提供从政策理解到落地执行的一站式解决方案。

cdfunlove的博客 389

JMM之重排序

重排序定义 在前面我们提到过,重排序是编译器和处理器为了优化程序性能而对指令序列重新排序的一种手段。但是我们也知道代码不可能毫无原则的进行重排序,如果是毫无原则的进行重排序,那么我们的代码将无法获得预期的结果。因此重排序必须满足如下原则: 在单线程中不改变运行结果 操作不具备数据依赖性 那这两条原则如何理解么,我们先来看看下面的定义 数据依赖性 数据依赖性的意思是,若果两个操作访问同一个变...

zhangzw的博客 321

【教程4>第5章>第28节】基于帧同步+相位同步+位同步的QPSK调制解调通信系统整体性能分析

综上所述:1.SNR<10db时,整体性能下降,当SNR=0db时,系统无法正常工作。2.gardner环性能达到2.5e-5时偏可以正常工作,增加之后无法正常工作。3.当相位偏差大于pi/4的时候,对最后的性能会有一定影响。

FPGA/MATLAB学习教程/源码/项目合作开发 555

RT-DETR改进策略【小目标改进】| Shape-NWD:融合改进,结合Shape-IoU和NWD 更好地适应小目标特性

Bw−wgt2h−hgt2weight2Bweight2w−wgt​2h−hgt​2​其中weight2weight = 2weight2。

Limiiiing的博客 1543

JUC并发编程 04——Java内存模型之JMM

JUC并发编程 04——Java内存模型之JMM

qq_62767608的博客 1307

【AI智能体】Codex 浏览器操作自动化任务实战操作详解

【AI智能体】Codex 浏览器操作自动化任务实战操作详解

congge 4039

奇怪的并发现象探究——JMM的指令重排、内存级指令重排

我们在平时所习惯的单线程编程中默认了一种乐观的模型——串行一致性。即在程序中只存在唯一的操作执行顺序,并且在每次读取变量时,都能获得在执行序列(任何处理器)最近一次写入该变量的值。但在JMM以及底层的任何一看现代多处理器架构中都不会提供这种串行一致性。这在并发编程中会造成一些在单线程环境下看来难以理解的现象。   比如,如下的java代码: package pack; public

Pandoras Box 2952

android 蓝牙通讯demo

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

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java并发与多线程(1)——指令重排与JMM

一、指令重排与JMM一、指令重排与JMM1.1 数据依赖性1.2 as-if-serial语义1.3 重排序概念1.4 重排序对多线程的影响1.5 Java内存模型(JMM)1.5.1 JMM抽象模型结构1.5.2 Happens-Before规则1.5.3 JMM如何解决重排序问题1.5.4 volidate关键字 如果觉得有用可以关注一下公众号:求赞求关注 一、指令重排一、指令重排与JMM1.1 数据依赖性1.2 as-if-serial语义1.3 重排序概念1.4 重排序对多线程的影响1.5 Jav

SpringBoy的博客 823

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

JMM内存模型之指令重排序问题

今天下午学习了下JMM内存模型的指令重排序问题。 关于指令重排序问题,有几个问题想问下。 问题一:如果发生指令重排序,是不是线程A和线程B的同时发生的?个人感觉只有这样才会出现x=0 y=0 问题二:以下代码的重排序是发生在CPU 中还是编译阶段? 问题三:指令重排序是随机发生的?每次都要运行到一定时间才会随机出现x=0 y=0那种情况。 问题四:为什么有时候已经打印出了x=0,y=0,后面还有x...

weixin_42882491的博客 362

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

jmm 指令重排 缓存可见性 Volatile 内存屏障

CPU是先操作自己的缓存,然后更新到内存中,其他CPU在从内存中获取更新的数据,更新到自己的缓存中,由于内存是隔一段时间刷新一次从缓存中获取最新数据而不是实时的,所以产生缓存一致性问题,也就是CPU自己的缓存对其他CPU不可见。这就是CPU缓存可见性问题。CPU指令重排是指CPU为了提高指令执行效率,可能会对指令的执行顺序进行优化,使得(单线程下)指令的实际执行顺序与代码中的顺序不同,但结果是一致的。Volatile通过内存屏障可以禁止指令重排序,内存屏障是一个CPU的指令,它可以保证特定操作的执行顺序。

qq_35740095的博客 473

理解 Java 内存模型(JMM)与 volatile 关键字 以及 指令重排

Java 内存模型(JMM)定义了多线程环境下变量的访问规则,确保可见性、有序性和原子性。volatile关键字是 JMM 中的一种轻量级同步机制,用于保证变量的可见性和有序性,但它不能保证原子性。在多线程编程中,合理使用volatile可以避免一些常见的并发问题,但在需要原子操作的场景中,仍需使用其他同步机制。

秃头之旅 1201

JMM中的指令重排,Volatile关键字(内存屏障)

JMM的概念 Java内存模型,不存在的东西,概念!约定! 关于JMM的一些同步的约定: 1、线程解锁前,必须把共享变量立刻刷回主存。 2、线程加锁前,必须读取主存中的最新值到工作内存中! 3、加锁和解锁是同一把锁 线程、工作内存与主存之间的关系 内存交互操作有8种,虚拟机实现必须保证每一个操作都是原子的,不可在分的(对于double和long类型的变量来说,load、store、read和write操作在某些平台上允许例外) lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态 un

qq_40340159的博客 407

Java内存模型(JMM)与指令重排

Java内存模型(JMM)是什么 缓存一致性 JMM为何存在 指令重排 happens-before

citricl 641

volatile指令重排_JMM Cookbook(一)指令重排

指令重排对于编译器的编写者来说,Java内存模型(JMM)主要是由禁止指令重排的规则所组成的,其中包括了字段(包括数组中的元素)的存取指令和监视器(锁)的控制指令。Volatile与监视器JMM中关于volatile和监视器主要的规则可以被看作一个矩阵。这个矩阵的单元格表示在一些特定的后续关联指令的情况下,指令不能被重排。下面的表格并不是JMM规范包含的,而是一个用来观察JMM模型对编译器和运行系...

weixin_39640085的博客 155

JVM(二) JMM、指令重排等

JSR 规范 Java Memory Model (JSR 133) JSR133中文版:http://ifeve.com/wp-content/uploads/2014/03/JSR133%E4%B8%AD%E6%96%87%E7%89%881.pdf JSR133: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf JMM(Java Memory Model (java内存模型 ≠ java虚拟内存模型)) JMM 是一种符合内存规范的,屏

qq_38895905的博客 710

volatile原理 JMM内存模型 指令重排

一.volatile (它的应用涉及到单例模式(具体是指volatile禁止了指令重排,所以可以让双端检锁实现线程安全)) 先说原理: 在生成汇编代码时,会在有volatile变量修饰的共享变量进行写操作的时候会多出Lock前缀的指令,通过查IA-32架构软件开发者手册可知,lock前缀的指令在多核处理器下会引发了两件事情。 * 将当前处理器缓存行的数据写回到系统内存。 * 这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。 处理器为了提高处理速度,不直接和内存进行通讯,而.

weixin_37695911的博客 314

JMM Cookbook(一)指令重排

原文地址:http://gee.cs.oswego.edu/dl/jmm/cookbook.html 第一章 译者:欧振聪 校对:李同杰 前言指令重排内存屏障多处理器指南 指令重排 对于编译器的编写者来说,Java内存模型(JMM)主要是由禁止指令重排的规则所组成的,其中包括了字段(包括数组中的元素)的存取指令和监视器(锁)的控制指令。 Volatile与监视器 JMM中关于vola

notOnlyRush的博客 433

JMM 三大特性 : 可见性,不保证原子性,禁止指令重排

我们大家都知道JVM是java虚拟机,那JMM是什么呢?是java内存模型. JMM全名为Java Memory Model,本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量,(包括实例字段,静态字段,和构成数组对象的元素)的访问方式. 接下来说它的三大特性: 1.可见性.可见性就是线程对变量的操作 ,必须在工作内存中进行,首先要将变量从...

樊建华 1337

深入剖析volatile:从JMM到指令重排的实战指南

本文深入剖析了volatile关键字在Java多线程编程中的核心特性与应用场景,包括可见性、原子性和指令重排。通过JMM内存模型解析和实战案例,展示了volatile如何解决多线程环境下的数据一致性问题,并提供了性能优化建议和常见误区分析。

data3的博客 714
上一篇: block,inline和inline-block概念和区别
下一篇: redis常用命令
startFromWeb
博客等级 码龄16年 23粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值