【发布时间】:2021-04-09 15:37:12
【问题描述】:
我对如何使用 OpenMP 多线程来并行化我正在使用的这个 for 循环有点困惑。在程序的这个程序部分中,我尝试从数组 x 和 y 接收数据;定义为:
x = (float*)aligned_alloc(32, sizeof(float) * n);
y = (float*)aligned_alloc(32, sizeof(float) * n);
其中 n 是大于 0 且可除以 16 的 int,然后将最大/最小 x/y 值保存在向量 maxX、minX、minY 和 maxY 中。 n 可以尽可能大,但在测试时我的 n 为 360000000。
我试图与多线程并行化的 for 循环是
for(int i = 8; i < n; i+= 8 ){
__m256 vx = _mm256_load_ps(&x[i]);
__m256 vy = _mm256_load_ps(&y[i]);
minX = _mm256_min_ps(minX, vx);
maxX = _mm256_max_ps(maxX, vx);
minY = _mm256_min_ps(minY, vy);
maxY = _mm256_max_ps(maxY, vy);
}
其中 minX、maxX、minY 和 maxY 是用零填充的 _m256 个向量。
到目前为止,我的尝试使我让每个线程都有自己的私有临时变量,用于 minX、maxX、minY 和 maxY,在 for 循环中处理,然后尝试将私有变量合并到共享变量中将在程序的其余部分中使用,如下所示:
#pragma omp parallel num_threads(4)
{
__m256 TempMinX = _mm256_load_ps(&x[0]); //creaing private variables for each thread
__m256 TempMaxX = _mm256_load_ps(&x[0]);
__m256 TempMinY = _mm256_load_ps(&x[0]);
__m256 TempMaxY = _mm256_load_ps(&x[0]);
#pragma omp for
for (int i = 8; i < n; i += 8) {
__m256 vx = _mm256_load_ps(&x[i]); //loads the values from the x array
__m256 vy = _mm256_load_ps(&y[i]); //loads the values from the y array
TempMinX = _mm256_min_ps(TempMinX, vx);
TempMaxX = _mm256_max_ps(TempMaxX, vx);
TempMinY = _mm256_min_ps(TempMinY, vy);
TempMaxY = _mm256_max_ps(TempMaxY, vy);
}
/*section to merge thread private variables into
the shared variables by comparing the
values in vector minX with the threads private
vector Temp and saving the smalles/largest
values in the shared vector: */
#pragma omp critical
minX = _mm256_min_ps(minX, TempMinX);
#pragma omp critical
maxX = _mm256_max_ps(maxX, TempMaxX);
#pragma omp critical
minY = _mm256_min_ps(minY, TempMinY);
#pragma omp critical
maxY = _mm256_max_ps(maxY, TempMaxY);
当运行这个程序并将其与“未并行化”程序进行比较时,“未并行化”程序比我的“并行化”程序运行得更快。我怀疑这可能与“合并”部分有关,其中不同的线程必须等待其他线程访问共享变量才能写入它,但到目前为止我还没有找到/想出任何好的解决方案关于如何解决这个问题并让它运行得更快...
【问题讨论】:
标签: c++ multithreading performance parallel-processing openmp