使用openmp并行化的嵌套循环

时间:2019-05-09 04:55:16

标签: c openmp

我正在尝试使用嵌套循环并行化一个函数。但是我没有得到正确的答案

我尝试打印中间值以查看出了什么问题。启用打印后,结果是正确的,但是禁用打印时,结果是错误的。

同时并行处理3个循环以使速度比串行实现更好的最佳方法是什么?

typedef struct
{
  float r;
  float i;
} mycomplex;

mycomplex z_num, p_data[128][4][256], z_data, z_temp, p_temp[256];

    {
#pragma omp parallel private(i) shared(w_myInd)
        for (i = 0; i < 128; i++)
        {
            w_myInd = w_globalInd[i];

#pragma omp parallel private(j, z_num)
            for (j = 0; j < 4; j++)
            {
                z_num.r = p_num[w_myInd][j].r;
                z_num.i = p_num[w_myInd][j].i;

#pragma omp parallel for num_threads(4) schedule(static, 16) \
        shared(i, j, z_num, p_temp, p_data) \
        private(k, z_data, z_temp)
                for (k = 0; k < 256; k++)
                {
                    tid = omp_get_thread_num();

                    z_data.r = p_data[i][j][k].r;
                    z_data.i = p_data[i][j][k].i;

                    z_temp.r = (z_data.r * z_num.r) - (z_data.i * z_num.i);
                    z_temp.i = (z_data.r * z_num.i) + (z_data.i * z_num.r);

                    p_temp[k].r = z_temp.r;
                    p_temp[k].i = z_temp.i;

                    //fprintf(fp, "tid = %d, (ijk) = (%d, %d, %d), z_num = (%e, %e), z_data = (%e, %e), z_temp = (%e, %e)\n",
                    //        tid, i, j, k, z_num.r, z_num.i, z_data.r, z_data.i, z_temp.r, z_temp.i);
                }
#pragma omp critical
                for (k = 0; k < 256; k++)
                {
                    p_data[i][j][k] = p_temp[k];
                }
            }
        }

已编辑

感谢您的反馈。

我现在只使用了1个循环,摆脱了关键部分。性能仍然不比串行实现好。我正在使用VS2017编译代码并在Intel i7处理器上对其进行测试。第一次代码需要17毫秒,此后每隔1毫秒或更短的时间,而此过程的串行实现总是在2-5毫秒左右。

是否还有其他调整可以提高此代码的速度?与第一次迭代的串行实现相比,为什么要花四倍以上的时间?

#pragma omp parallel for num_threads(16) schedule(static, 16) \
    private(i, j, k, z_data, z_temp, w_myInd, z_num)
    for (ijk = 0; ijk < 128*4*256; ijk++)
    {
        i = ijk / (256* 4);
        j = (ijk - (i * 256* 4))/256;
        k = ijk - (i * 256* 4)  - (j * 256);

        w_myInd = w_globalInd[i];

        z_num.r = p_num[w_myInd][j].r;
        z_num.i = p_num[w_myInd][j].i;

        z_data.r = p_data[i][j][k].r;
        z_data.i = p_data[i][j][k].i;

        z_temp.r = (z_data.r * z_num.r) - (z_data.i * z_num.i);
        z_temp.i = (z_data.r * z_num.i) + (z_data.i * z_num.r);

        p_data[i][j][k] = z_temp;
    }

0 个答案:

没有答案