减少 OpenMP 中的数组
OpenMP 为大量应用程序提供并行执行功能。然而,出现了一个关于数组缩减的常见问题,OpenMP 并不直接支持数组缩减。
替代解决方案
虽然本机数组缩减不可用,但还有其他替代方法在 C/C 中实现类似的功能:
方法 1:使用 Critical 进行私有数组缩减部分
在这种方法中,每个线程都对数组的私有副本进行操作,累积其贡献。当所有线程完成后,将使用临界区将各个数组元素合并到原始数组中。
int S [10] = {0}; #pragma omp parallel { int S_private[10] = {0}; #pragma omp for for (int n=0 ; n<10 ; ++n ) { for (int m=0; m<=n; ++m){ S_private[n] += A[m]; } } #pragma omp critical { for(int n=0; n<10; ++n) { S[n] += S_private[n]; } } }
方法 2:线程局部数组缩减
此方法通过创建维度为 10*nthreads 的中间数组来消除临界区。线程并行填充该数组,然后将其合并到原始数组中。
int S [10] = {0}; int *S_private; #pragma omp parallel { const int nthreads = omp_get_num_threads(); const int ithread = omp_get_thread_num(); #pragma omp single { S_private = new int[10*nthreads]; for(int i=0; i<(10*nthreads); i++) S_private[i] = 0; } #pragma omp for for (int n=0 ; n<10 ; ++n ) { for (int m=0; m<=n; ++m){ S_private[ithread*10+n] += A[m]; } } #pragma omp for for(int i=0; i<10; i++) { for(int t=0; t<nthreads; t++) { S[i] += S_private[10*t + i]; } } } delete[] S_private;
这些方法克服了 OpenMP 中原生数组缩减的不足,允许并行高效累积数组元素。
以上是当 OpenMP 不直接支持数组缩减时,如何实现数组缩减?的详细内容。更多信息请关注PHP中文网其他相关文章!