【问题标题】:What is "false sharing"? How to reproduce / avoid it?什么是“虚假分享”?如何重现/避免它?
【发布时间】:2014-05-11 01:33:02
【问题描述】:

今天我和教授在并行编程课上对什么是“虚假共享”有了不同的理解。我的教授说的没有道理,所以我立即指出。她认为“虚假分享”会导致节目结果出现错误。

我说过,当不同的内存地址分配给同一个缓存行时,会发生“错误共享”,将数据写入其中一个会导致另一个被踢出缓存。如果处理器在两个虚假共享地址之间来回写入,则它们都无法停留在缓存中,因此所有操作都会导致对DRAM的访问。

到目前为止,这是我的看法。事实上,我也不确定我说的是什么……如果我有误解,请指出来。

所以有一些问题。缓存假定为 64 字节对齐、4 路组关联。

  1. 两个超过 64 字节的地址是否有可能是“虚假共享”?
  2. 单线程程序是否可能遇到“错误共享”问题?
  3. 重现“虚假共享”的最佳代码示例是什么?
  4. 一般来说,避免程序员“虚假共享”的注意事项有哪些?

【问题讨论】:

  • here是一个关于虚假分享的视频,希望对您有所帮助。没有50声望不能加评论,真的很尴尬。

标签: caching optimization parallel-processing computer-architecture false-sharing


【解决方案1】:

我会就你的问题分享我的观点。

  1. 由比块大小更多的字节分隔的两个地址不会驻留在完全相同的高速缓存行上。因此,如果一个内核在其缓存中具有第一个地址,而另一个内核请求第二个地址,则第一个内核不会因为该请求而从缓存中删除。所以不会发生错误的分享失误。

  2. 我无法想象在完全没有并发的情况下会发生多么错误的共享,因为除了单个线程之外没有其他人来竞争缓存行。

  3. 取自here,使用 OpenMP,重现虚假共享的简单示例是:

    double sum=0.0, sum_local[NUM_THREADS];
    
    #pragma omp parallel num_threads(NUM_THREADS)
    {
        int me = omp_get_thread_num();
        sum_local[me] = 0.0;
    
        #pragma omp for
        for (i = 0; i < N; i++)
            sum_local[me] += x[i] * y[i];
    
        #pragma omp atomic
        sum += sum_local[me];
    }
    
  4. 为了避免虚假分享,我能想到的一些一般注意事项是:

    一个。尽可能使用私人数据。

    b.有时您可以使用padding 来对齐数据,以确保没有其他变量将驻留在共享数据所在的同一缓存中。

欢迎任何更正或补充。

【讨论】:

  • 启用优化后,任何体面的编译器都会将sum_local[me] 保存在寄存器中,除非它不能证明x[i]y[i] 不能为它起别名。 (并且一些编译器会在运行时发出代码来检查重叠,并在这种情况下使用自动矢量化循环。否则,即使没有错误共享,潜在的混叠也会使循环变得糟糕;只需额外的 5 个存储转发延迟周期而无需循环携带的依赖链中的错误共享非常糟糕)。但是,是的,任何稍微复杂的事情都很容易在循环内部产生错误的共享,而不仅仅是在结束时。
  • @PeterCordes 如果 NUM_THREADS 不是常数怎么办?我不认为编译器可以在这种情况下分配寄存器
  • @tuket:没关系。它只需要证明foo[bar] 每次循环都是同一个地址,并且写入它不会影响我们从x[i]y[i] 读取的内容。 (例如 sum_local[] 不与 x[]y[] 重叠)。由于me 是循环不变的并且sum_local 是一个数组,因此编译器可以在循环内的寄存器中保存一个和,并在最后使用me 的运行时变量值存储一次。每个线程都有自己的me,并且知道C99 VLA的基地址double sum_local[NUM_THREADS];
  • @tuket:无论哪种方式,理想情况下,您都可以让每个线程只使用自己的私有标量变量,但此示例的重点是演示虚假共享,因此故意将其写成“糟糕”。不过,我仍然认为您必须在禁用优化的情况下进行编译,以阻止编译器将其优化为寄存器。或volatile double sum_local[NUM_THREADS];
猜你喜欢
  • 2015-07-01
  • 2017-01-19
  • 2017-02-14
  • 2013-01-09
  • 1970-01-01
  • 2021-11-29
  • 2018-10-20
  • 1970-01-01
  • 2016-01-02
相关资源
最近更新 更多