网站建设后的注意问题学做电商需要多少钱
news/
2025/9/22 19:46:09/
文章来源:
网站建设后的注意问题,学做电商需要多少钱,自豪地采用wordpress 删除,英雄联盟网页制作素材本文所讨论的计算机模型是Shared Memory Multiprocessor#xff0c;即我们现在常见的共享内存的多核CPU。本文适合的对象是想用C 或者Java进行多线程编程的程序员。本文主要包括对Sequential Consistency和Cache Coherence的概念性介绍并给出了一些相关例子#xff0c;目的是… 本文所讨论的计算机模型是Shared Memory Multiprocessor即我们现在常见的共享内存的多核CPU。本文适合的对象是想用C 或者Java进行多线程编程的程序员。本文主要包括对Sequential Consistency和Cache Coherence的概念性介绍并给出了一些相关例子目的是帮助程序员明白为什么需要在并行编程时关注Sequential Consistency。Sequential Consistency下文简称SC是Java内存模型和即将到来的C 0x内存模型的一个关键概念它是一个最直观最易理解的多线程程序执行顺序的模型。Cache Coherence下文简称CC是多核CPU在硬件中已经实现的一种机制简单的说它确保了对在多核CPU的Cache中一个地址的读操作一定会返回那个地址最新的被写入的值。那么为什么程序员需要关心SC呢因为现在的硬件和编译器出于性能的考虑会对程序作出违反SC的优化而这种优化会影响多线程程序的正确性也就是说你用C 编写的多线程程序可能会得到的不是你想要的错误的运行结果。Java从JDK1.5开始加入SC支持所以Java程序员在进行多线程编程时需要注意使用Java提供的相关机制来确保你程序的SC。程序员之所以不需要关心CC的细节是因为现在它已经被硬件给自动帮你保证了不是说程序员完全不需要关心CC实际上对程序员来说理解CC的大致工作原理也是很有帮助的典型的如避免多线程程序的伪共享问题即False Sharing。那么什么是SC什么是CC呢1.Sequential Consistency (顺序一致性SC的作者Lamport给的严格定义是“… the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.”这个概念初次理解起来拗口不过不要紧下面我会给出个很直观的例子帮助理解。假设我们有两个线程线程1和线程2分别运行在两个CPU上有两个初始值为0的全局共享变量x和y两个线程分别执行下面两条指令初始条件x y 0;线程 1线程 2x 1;y1;r1 y;r2 x;因为多线程程序是交错执行的所以程序可能有如下几种执行顺序Execution 1Execution 2Execution 3x 1;r1 y;y 1;r2 x;结果:r10 and r2 1y 1;r2 x;x 1;r1 y;结果: r1 1 and r2 0x 1;y 1;r1 y;r2 x;结果: r1 1 and r2 1当然上面三种情况并没包括所有可能的执行顺序但是它们已经包括所有可能出现的结果了所以我们只举上面三个例子。我们注意到这个程序只可能出现上面三种结果但是不可能出现r10 and r20的情况。SC其实就是规定了两件事情1每个线程内部的指令都是按照程序规定的顺序program order执行的单个线程的视角2线程执行的交错顺序可以是任意的但是所有线程所看见的整个程序的总体执行顺序都是一样的整个程序的视角第一点很容易理解就是说线程1里面的两条语句一定在该线程中一定是x1先执行r1y后执行。第二点就是说线程1和线程2所看见的整个程序的执行顺序都是一样的举例子就是假设线程1看见整个程序的执行顺序是我们上面例子中的Execution 1那么线程2看见的整个程序的执行顺序也是Execution 1不能是Execution 2或者Execution 3。有一个更形象点的例子。伸出你的双手掌心面向你两个手分别代表两个线程从食指到小拇指的四根手指头分别代表每个线程要依次执行的四条指令。SC的意思就是说1对每个手来说它的四条指令的执行顺序必须是从食指执行到小拇指2你两个手的八条指令八根手指头可以在满足1的条件下任意交错执行例如可以是左1左2右1右2右3左3左4右4也可以是左1左2左3左4右1右2右3右4也可以是右1右2右3左1左2右4左3左4等等等等其实说简单点SC就是我们最容易理解的那个多线程程序执行顺序的模型。2. Cache Conherence 缓存一致性那么CC是干什么用的呢这个要详细说的话就复杂了写一本书绰绰有余。简单来说我们知道现在的多核CPU的Cache是多层结构一般每个CPU核心都会有一个私有的L1级和L2级Cache然后多个CPU核心共享一个L3级缓存这样的设计是出于提高内存访问性能的考虑。但是这样就有一个问题了每个CPU核心之间的私有L1L2级缓存之间需要同步啊。比如说CPU核心1上的线程A对一个共享变量global_counter进行了加1操作这个被写入的新值存到CPU核心1的L1缓存里了此时另一个CPU核心2上的线程B要读global_counter了但是CPU核心2的L1缓存里的global_counter的值还是旧值最新被写入的值现在还在CPU核心1上呢怎么把这个任务就交给CC来完成了CC是Cache之间的一种同步协议它其实保证的就是对某一个地址的读操作返回的值一定是那个地址的最新值而这个最新值可能是该线程所处的CPU核心刚刚写进去的那个最新值也可能是另一个CPU核心上的线程刚刚写进去的最新值。举例来说上例的Execution 3中r1 y是对y进行读操作该读操作一定会返回在它之前已经执行的那条指令y1对y写入的最新值。可能程序员会说这个不是显而意见的么r1肯定是1啊因为y1已经执行了。其实这个看似简单的”显而易见“在多核processor的硬件实现上是有很多文章的因为y1是在另一个CPU上发生的事情你怎么确保你这个读操作能立刻读到别的CPU核心刚刚写入的值不过对程序员来讲你不需要关心CC因为CPU已经帮你搞定这些事情了不用担心多核CPU上不同Cache之间的同步的问题了感兴趣的朋友可以看看体系结构的相关书籍现在的多核CPU一般是以MESI protocol为原型来实现CC。总结一下CC和SC其实是相辅相承的前者保证对单个地址的读写正确性后者保证整个程序对多个地址读写的正确性两者共同保证多线程程序执行的正确性。3. 为什么要关心SC好回到SC的话题。为什么说程序员需要关心SC因为现在的CPU和编译器会对代码做各种各样的优化有时候它们可能会为了优化性能而把程序员在写程序时规定的代码执行顺序(program order)打乱导致程序执行结果是错误的。例如编译器可能会做如下优化即把线程1的两条语序调换执行顺序初始条件xy0;线程 1线程 2r1 y;y1;x 1;r2 x;那么这个时候程序如果按如下顺序执行就可能就会出现r1r20这样程序员认为”不正确“的结果Execution 4r1 y;y 1;r2 x;x 1;为什么编译器会做这样的优化呢因为读一个在内存中而不是在cache中的共享变量需要很多周期所以编译器就”自作聪明“的让读操作先执行从而隐藏掉一些指令执行的latency提高程序的性能。实际上这种类似的技术是在单核时代非常普遍的优化方法但是在进入多核时代后编译器没跟上发展导致了对多线程程序进行了违反SC的错误优化。为什么编译器很难保证SC因为对编译器来讲它很难知道多个线程在执行时会按照什么样的交错顺序执行因为这需要一个整个程序运行时的视角而只对一份静态的代码做优化的编译器是很难得到这种运行时的上下文的。那么为什么硬件也保证不了呢因为CPU硬件中的写缓冲区store buffer会把要写入memory的值缓存起来然后当前线程继续往下执行而这个被缓存的值可能要很晚才会被其他线程“看见”从而导致多线程程序逻辑出错。其实硬件也提供了一些例如Memory Barrier等解决方案但是开销是一个比较大的问题而且很多需要程序员手动添加memory barrier现在还不能指望CPU或者编译器自动帮你搞定这个问题。感兴趣的朋友可以在本文的参考文献中发现很多硬件优化造成SC被违反的例子以及Memory Barrier等解决方案好了我们发现为了保证多线程的正确性我们希望程序能按照SC模型执行但是SC的对性能的损失太大了CPU硬件和编译器为了提高性能就必须要做优化啊为了既保证正确性又保证性能在经过十几年的研究后一个新的新的模型出炉了sequential consistency for data race free programs。简单地说这个模型的原理就是对没有data race的程序可以保证它是遵循SC的这个模型在多线程程序的正确性和性能间找到了一个平衡点。对广大程序员来说我们依赖高级语言内建的内存模型来帮我们保证多线程程序的正确性。例如从JDK1.5开始引入的Java内存模型中已经支持data race free的SC了例如使用volatile关键字atomic变量等但是C 程序员就需要等待C 0x中新的内存模型的atomic类型等来帮助保证SC了(因为atomic类型的值具有acquire和release语义它隐式地调用了memory barrier指令)。什么意思呢说简单点就是由程序员用同步原语例如锁或者atomic的同步变量来保证你程序是没有data race的这样CPU和编译器就会保证你程序是按你所想的那样执行的即SC是正确的。换句话说程序员只需要恰当地使用具有acquire和release语义的同步原语标记那些真正需要同步的变量和操作就等于告诉CPU和编译
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910168.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!