Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency 全球共享计数器的实现_Concurrency_X86_Memory Barriers - Fatal编程技术网

Concurrency 全球共享计数器的实现

Concurrency 全球共享计数器的实现,concurrency,x86,memory-barriers,Concurrency,X86,Memory Barriers,以下代码来自(清单5.3): 上面的代码实现了一个全局(由内核共享)计数器。显然,我们可以用原子操作来代替。然而,我们考虑更新非常频繁的情况,所以我们需要一个每个线程变量来最小化CPU系统上的流量。 我不明白为什么它是正确的。毕竟,在C/C++/Java中,我们最多有SC-DRF(如果没有数据竞争,则顺序一致性) 事实上,我们有一场数据竞赛。因此,我们无法从内存模型中得到保证。特别是,关于超薄值的呢?我看不出如何保证它不会发生。那么,你认为呢?就我的疑问而言,该实现正确吗?为什么?不确定您所指

以下代码来自(清单5.3):

上面的代码实现了一个全局(由内核共享)计数器。显然,我们可以用原子操作来代替。然而,我们考虑更新非常频繁的情况,所以我们需要一个每个线程变量来最小化CPU系统上的流量。 我不明白为什么它是正确的。毕竟,在
C/C++/Java
中,我们最多有
SC-DRF
(如果没有数据竞争,则顺序一致性)


事实上,我们有一场数据竞赛。因此,我们无法从内存模型中得到保证。特别是,关于超薄值的
呢?我看不出如何保证它不会发生。那么,你认为呢?就我的疑问而言,该实现正确吗?为什么?

不确定您所指的文档的哪个版本,但中的图5.3使用了宏
READ_ONCE
WRITE_ONCE
,它们提供了跨线程的基本可见性保证。当与计数器的正确对齐相结合时,然后我假设它本质上等同于放松的原子语义。

不确定您所指的文档的哪个版本,但中的图5.3使用了宏
READ\u ONCE
WRITE\u ONCE
,它们提供了跨线程的基本可见性保证。当与计数器的正确对齐相结合时,我认为它本质上等同于放松的原子语义。

\uuuuuu-get\uu-therad\uvar
看起来像一个打字错误。那真的是原作吗?无论如何,如果要避免数据竞争,显然只能在所有写入线程停止后运行
read\u count
。否则它是UB,但在正常系统上的实际情况是可以的,因为在大多数平台上,自然对齐的
long
加载恰好是原子的。但如果在循环中调用,则不安全,如果……PeterCordes,我已经编辑过了。“松弛的、无用的”C++语义允许了松弛原子。它们不可能在现实生活中发生。
\uuuu get\uu therad\uvar
看起来像一个打字错误。那真的是原作吗?无论如何,如果要避免数据竞争,显然只能在所有写入线程停止后运行
read\u count
。否则它是UB,但在正常系统上的实际情况是可以的,因为在大多数平台上,自然对齐的
long
加载恰好是原子的。但如果在循环中调用,则不安全,如果……PeterCordes,我已经编辑过了。“松弛的、无用的”C++语义允许了松弛原子。它们不可能发生在现实生活中。
DEFINE PER_THREAD(long, counter);

void inc_count(void){
  __get_thread_var(counter)++; // __get_thread_var returns a reference to thread local counter.  
}

long read_count(void){
    int t;
    long sum = 0;

    for_each_thread(t)
       sum += per_thread(counter, t);
    return sum;
}