您的问题实际上是我曾经提出的一个问题的重复。 使用OpenMP在不使用临界区的情况下并行填充直方图。
在您的情况下,简单的解决方案是
#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("");
}
b
大小的比例(它真的总是10吗?)。一个更简单的替代方案是使用一系列互斥锁。 - Brian Cain