什么是"虚假分享"?如何重现/避免它?

Aea*_*ean 8 parallel-processing optimization caching computer-architecture false-sharing

今天我和我的教授在并行编程课上有了不同的理解,关于什么是"虚假共享".我的教授所说的没什么意义,所以我立即指出了.她认为"虚假分享"会导致程序结果出错.

我说,"错误共享"发生在将不同的内存地址分配给同一个缓存行时,将数据写入其中一个会导致另一个被踢出缓存.如果处理器在两个错误共享地址之间写入转向和转向,则它们都不能停留在高速缓存上,因此所有操作都将导致DRAM的访问.

到目前为止,这是我的意见.事实上,我不确定我说的是什么......如果我有误解,请指出.

所以有一些问题.假设缓存为64字节对齐,4路组关联.

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

chr*_*hrk 11

我将针对您的问题分享我的观点。

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

  2. 我无法想象当根本没有并发时会如何发生错误共享,因为除了单个线程之外不会有其他人竞争缓存行。

  3. 从这里开始,使用 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];
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 我能想到的避免虚假共享的一些一般注意事项是:

    A。尽可能使用私有数据。

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

欢迎任何修正或补充。