代码之家  ›  专栏  ›  技术社区  ›  R zu

多核错误共享

  •  1
  • R zu  · 技术社区  · 6 年前

    以下程序中是否会发生错误共享?

    记忆

    • 1个数组分为4个相等的区域: [A1, A2, B1, B2]
    • 每个区域填充为64字节的倍数。

    步骤

    1. thread 1 write to region A1 and A2 while thread 2 write to region B1 and B2.
    2. barrier
    3. thread 1 read B1 and write to A1 while thread 2 read B2 and write to A2.
    4. barrier
    5. Go to step 1.
    

    #include <vector>
    #include <iostream>
    #include <stdint.h>
    int main() {
        int N = 64;
        std::vector<std::int32_t> x(N, 0);
        #pragma omp parallel
        {
            for (int i = 0; i < 1000; ++i) {
                #pragma omp for
                for (int j = 0; j < 2; ++j) {
                    for (int k = 0; k < (N / 2); ++k) {
                        x[j*N/2 + k] += 1;
                    }
                }
                #pragma omp for
                for (int j = 0; j < 2; ++j) {
                    for (int k = 0; k < (N/4); ++k) {
                        x[j*N/4 + k] += x[N/2 + j*N/4 + k] - 1;
                    }
                }
            }
        }
        for (auto i : x ) std::cout << i << " ";
        std::cout << "\n";
    }
    

    结果

    32 elements of 500500 (1000 * 1001 / 2)
    32 elements of 1000
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Zulan    6 年前

    你的代码中有一些错误共享,因为 x 不能保证与缓存线对齐。填充不一定足够。在你的例子中 N 真的很小,这可能是个问题。注意你的例子 N ,最大的开销可能是工作共享和线程管理。如果 N 足够大,即。 array-size / number-of-threads >> cache-line-size ,虚假分享不是相关问题。

    A2

    注意,不需要拆分循环。如果您在一个循环中连续地访问内存中的索引,一个循环就可以了。

    #pragma omp for
    for (int j = 0; j < N; ++j)
        x[j] += 1;
    

    如果你真的很小心,你可以加上 schedule(static)

    vector[my_thread_index] .

    推荐文章