您的位置:首页 > 其它

【翻译一】什么是内存模型

2017-03-17 00:00 295 查看
摘要: 每天睡前看看,自己翻译一遍,足足翻了一周。。。加深理解。

What is a memory model, anyway?

什么是内存模型

In multiprocessor systems, processors generally have one or more layers of memory cache, which improves performance both by speeding access to data (because the data is closer to the processor) and reducing traffic on the shared memory bus (because many memory operations can be satisfied by local caches.) Memory caches can improve performance tremendously, but they present a host of new challenges. What, for example, happens when two processors examine the same memory location at the same time? Under what conditions will they see the same value?

多核处理器一般有多级缓存,在缓存中,由于离处理器更近,使得访问数据速度更快速,而且本地缓存也可以满足大部分的内存操作,因此处理器与共享内存总线的交互也会变少。可以说,缓存大大提高了程序性能。

但是,缓存也随之带来了一大堆新的挑战,比如,两个处理器同时查询相同的一块内存,什么情况下才能看到相同的值呢?

At the processor level, a memory model defines necessary and sufficient conditions for knowing that writes to memory by other processors are visible to the current processor, and writes by the current processor are visible to other processors. Some processors exhibit a strong memory model, where all processors see exactly the same value for any given memory location at all times. Other processors exhibit a weaker memory model, where special instructions, called memory barriers, are required to flush or invalidate the local processor cache in order to see writes made by other processors or make writes by this processor visible to others. These memory barriers are usually performed when lock and unlock actions are taken; they are invisible to programmers in a high level language.

在处理器层面,内存模型定义了充要条件,以搞清楚多个处理器和唯一的内存之间的可见关系,如什么情况下其他处理器对内存的写入对当前处理器是可见的,或者什么情况下当前处理器对内存的写入对其他处理器是可见的。

部分处理器有着非常强的内存模型,使得所有核心在任何时间任何的内存位置,查询到的值都是一样的。但其余的处理器并不会有这么强的内存模型,它们为了看到别的处理器的写入,或者让别的处理器看到自己的写入,就需要用到内存屏障这样的特殊指令。

内存屏障通常在加锁和解锁时执行

内存屏障对使用高级语言的程序员是不可见的

It can sometimes be easier to write programs for strong memory models, because of the reduced need for memory barriers. However, even on some of the strongest memory models, memory barriers are often necessary; quite frequently their placement is counterintuitive. Recent trends in processor design have encouraged weaker memory models, because the relaxations they make for cache consistency allow for greater scalability across multiple processors and larger amounts of memory.

如果处理器是强内存模型的,那编程起来自当容易,因为根本不用理会内存屏障。然而,即使是强内存模型,也是会用到内存屏障的,由此导致极频繁的内存屏障指令也是不合常理的。

因此,处理器设计趋向于更加弱的内存模型,因为对保持内存一致的放宽,可以让多核处理器和大内存有更大的可扩展性。

The issue of when a write becomes visible to another thread is compounded by the compiler's reordering of code. For example, the compiler might decide that it is more efficient to move a write operation later in the program; as long as this code motion does not change the program's semantics, it is free to do so. If a compiler defers an operation, another thread will not see it until it is performed; this mirrors the effect of caching.

相比于处理器,对于一个线程写入操作,能否对其他线程可见的问题,同时受到编译器重排序的影响。例如,编译器也许会把一条写入操作放到程序最后,因为它觉得这样可以提高程序效率,这么看, 编译器还是很任性的嘛...不过只要移动代码不影响程序语义,那也就由着编译器了...可一旦编译器推迟了一行代码,在执行之前其他线程就都不会看到了,这也反映了缓存的效果

Moreover, writes to memory can be moved earlier in a program; in this case, other threads might see a write before it actually "occurs" in the program. All of this flexibility is by design -- by giving the compiler, runtime, or hardware the flexibility to execute operations in the optimal order, within the bounds of the memory model, we can achieve higher performance.

此外,对内存的写入也可能被放到程序的前面,这种情况下,其他线程会在这个写入操作本应发生前看到它。设计如此灵活的重排序,就是为了赋予编译器、运行时或者硬件以最佳的顺序灵活的执行程序命令。利用重排序和内存模型的约束,我们可以让程序表现的更好。

A simple example of this can be seen in the following code:

以下代码是一个重排序的简例:

Class Reordering {
int x = 0, y = 0;
public void writer() {
x = 1;
y = 2;
}

public void reader() {
int r1 = y;
int r2 = x;
}
}

Let's say that this code is executed in two threads concurrently, and the read of y sees the value 2. Because this write came after the write to x, the programmer might assume that the read of x must see the value 1. However, the writes may have been reordered. If this takes place, then the write to y could happen, the reads of both variables could follow, and then the write to x could take place. The result would be that r1 has the value 2, but r2 has the value 0.

在两条线程并发执行这段代码,并且读到y的值是2的情况下,程序员可能会假定x的值必定是1,因为y=2在x=1后面。但writer方法可能发生重排序,先y=2,后执行reader方法,然后x=1,导致r1=2,而r2=0。

The Java Memory Model describes what behaviors are legal in multithreaded code, and how threads may interact through memory. It describes the relationship between variables in a program and the low-level details of storing and retrieving them to and from memory or registers in a real computer system. It does this in a way that can be implemented correctly using a wide variety of hardware and a wide variety of compiler optimizations.

JMM描述了多线程编码中那些行为是合法的,以及线程间如何通过内存进行交互。它描述了在计算机中,程序中的变量,与变量在内存或寄存器中读写的底层细节,之间的关系。在某种程度上,JMM可以使用多种硬件和多种编译器优化来正确实现。

Java includes several language constructs, including volatile, final, and synchronized, which are intended to help the programmer describe a program's concurrency requirements to the compiler. The Java Memory Model defines the behavior of volatile and synchronized, and, more importantly, ensures that a correctly synchronized Java program runs correctly on all processor architectures.

Java在语言层面上有几个概念,包括volatile,final,synchronized,用来帮助程序员告诉编译器,程序应该如何并发运行。JMM中,volatile和synchronized尤为重要,它们确保了一个同步的程序在所有多核架构中正确运行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: