首页 >后端开发 >C++ >当 OpenMP 不直接支持数组缩减时,如何实现数组缩减?

当 OpenMP 不直接支持数组缩减时,如何实现数组缩减?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-04 07:00:12637浏览

How Can Array Reduction Be Achieved in OpenMP When It's Not Directly Supported?

减少 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn