观测器

JMMamp并发三大特性

发布时间:2022/5/9 20:29:40   
1.并发编程基础1.1本质

并发编程本质在硬件层面是去充分压榨CPU等硬件设备。为了达到这个目的,硬件设备进行了不断的迭代升级,从单任务执行,到单核多任务,再到现在的多核多任务阶段。随着压榨的方式变化,也带来了新的问题,比如不同进程如何通信?不同进程间的线程如何通信?

计算机发展到现在,线程成为CPU调度的基本单位,并发编程的本质在软件层面是去解决不同线程之间同步、互斥、分工问题。

1.2机械同感

从硬件和软件两个维度去把握并发编程,会有更好的效果,这有一个专业名词来形容:“机械同感”。

偶然在MartinFlower的博客上看到了一篇讲述LMAX架构的博文,里面有一小块提到了“机械同感”MechanicalSympathy(不知道该怎么翻译好)。恰逢最近正在看第二版的CSAPP(ComputerSystem:AProgrammerPerspective,深入理解计算机系统),感慨万千!

“机械同感”(mechanicalsympathy)来自于赛车比赛,它反映了车手对赛车有一种内在的感觉,所以他们能够赛车达到最佳状态。然而多数程序员缺少这种对编程与硬件交互的感同身受的情感。要么是没有,要么就是以为自己有,实际上却是基于很久以前硬件工作方式而建立的概念。这说得实在是太多,作为一个程序员,在写程序时是否考虑过自己的代码能否正确地运行在底层硬件上,又是否考虑过怎样榨干硬件性能让自己的代码跑得飞快,又是否考虑过自己的代码能否被人钻了空子发生安全问题。我想这三方面也许是学习硬件工作原理的最主要因素,即让自己的代码:正确、高效、安全地在硬件上跑。简单来说就是快准稳!

这同时又让我回忆起另一件事。曾经看过一些《一个操作系统的实现》写过一些汇编。一个很深的感触就是:代码万变不离其宗,无论怎样写都跳不出IntelX86的CPU和指令集。就像孙猴子跳不出如来佛的五指山一样,我们也没法写出超脱于底层硬件的代码。所以尽管软件世界风起云涌,各种新算法、新语言、新概念层出不穷,然而硬件世界确实波澜不惊。内核引导、LDT、GDT、Ring0到Ring3这些基本原理未曾变过,如此强烈的反差怎能不叫人感慨。

————————————————

版权声明:本文为CSDN博主「cdai」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:   //第一个volatile读intj=v2; //第二个volatile读a=i+j;//普通写v1=i+1; //第一个volatile写v2=j*2; //第二个volatile写}}

针对readAndWrite()方法,编译器在生成字节码时可以做如下的优化。

注意,最后的StoreLoad屏障不能省略。因为第二个volatile写之后,方法立即return。此时编译器可能无法准确断定后面是否会有volatile读或写,为了安全起见,编译器通常会在这里插入一个StoreLoad屏障。

上面的优化针对任意处理器平台,由于不同的处理器有不同“松紧度”的处理器内存模型,内存屏障的插入还可以根据具体的处理器内存模型继续优化。以X86处理器为例,上图除最后的StoreLoad屏障外,其他的屏障都会被省略。

前面保守策略下的volatile读和写,在X86处理器平台可以优化成如下图所示。前文提到过,X86处理器仅会对写-读操作做重排序。X86不会对读-读、读-写和写-写操作做重排序,因此在X86处理器中会省略掉这3种操作类型对应的内存屏障。在X86中,JMM仅需在volatile写后面插入一个StoreLoad屏障即可正确实现volatile写-读的内存语义。这意味着在X86处理器中,volatile写的开销比volatile读的开销会大很多(因为执行StoreLoad屏障开销会比较大)。

5.读写屏障总结

不同CPU对重排序实现不同,比如X86只会对写-读操作做重排序,因此JMM在不同硬件平台上对内存屏障的实现不同。

JMM会在保守的模式下,针对字节码文件,省略不必要的读写屏障,提升性能。

JVM是利用JMM规则,在编译字节码文件过程中,对字节码插入指令序列,防止特定类型的处理器重排序。

结构化程序员



转载请注明:http://www.aideyishus.com/lkcf/178.html

------分隔线----------------------------

热点文章

  • 没有热点文章

推荐文章

  • 没有推荐文章