c - 使用 OpenMP 并行递增数组元素

标签 c arrays for-loop openmp increment

我有一个大小为 N 的随机数数组 a。使用 OpenMP,我想为 A 中的每个数字增加大小为 10 的数组 b 的元素 0 到 9。语言是 C。

#pragma omp parallel for
for(i = 0; i < N; i++)
   b[a[i]]++;

不幸的是,b 的某些元素显然是同时写入的,结果与预期不符。我尝试将 b 设置为 firstprivate 和 lastprivate,但这也没有帮助。

这个任务看起来很简单,但我不知道该怎么做,因为在 OpenMP 中没有用于数组的 atomic。我可以为线程数创建一个新数组,然后在最后将它们加在一起,但这似乎不是最佳选择。

在数组 b 的元素中计算 a 中的数字出现次数的最快方法是什么?

最佳答案

你的问题本质上是我问过的问题的重复 fill-histograms-in-parallel-with-openmp-without-using-a-critical-section .

您的情况的简单解决方案是

#pragma omp parallel
{
    int i, b_local[10] = {0};
    #pragma omp for nowait 
    for(i = 0; i < n; i++) b_local[a[i]]++;
    #pragma omp critical
    for(i=0; i<10; i++) b[i] += b_local[i];    
}

可以在没有关键部分的情况下执行此操作(请参阅我的问题),但不一定更有效。

这是一个工作示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N 100

void foo(int *b, int *a, int n) {
    #pragma omp parallel
    {
        int i, b_local[10];
        memset(b_local, 0, 10*sizeof(int));
        #pragma omp for 
        for(i = 0; i < n; i++) b_local[a[i]]++;


        #pragma omp critical
        {     
            for(i=0; i<10; i++) {
                b[i] += b_local[i]; 
            }
        }

    }
}

int main() {   
    int i;
    int b[10] = {0,1,2,3,4,5,6,7,8,9};
    int b2[10] = {0,1,2,3,4,5,6,7,8,9};
    int a[N];
    for(i=0; i<N; i++) a[i] = rand()%10;

    foo(b,a,N);
    for(i=0; i<N; i++) b2[a[i]]++;
    for(i=0; i<10; i++) printf("%d ", b[i]); puts("");
    for(i=0; i<10; i++) printf("%d ", b2[i]); puts("");
}

关于c - 使用 OpenMP 并行递增数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29285110/

相关文章:

ios - 从数组中获取前 10 个对象

c - 输出不同——无法理解逻辑

c - 从共享内存读取段错误

c - 摆脱 C 中的尾随数字

python - 从 2d numpy 数组中提取旋转的 1d 轮廓的结果不一致

arrays - SUMIF 包含数组中的元素之一 (OR)

c - 在 Erlang 中表示 C 数组的最佳方式是什么?

c - 以编程方式按下另一个应用程序(C,Windows)上的按钮

javascript - 简单的js for循环只迭代一次

c++ - 如何在 for 循环中声明第二个迭代器?