【问题标题】:CUDA parallelizing work with arraysCUDA 并行处理数组
【发布时间】:2018-06-06 18:18:23
【问题描述】:

我是 CUDA 的新手,我刚刚阅读了一些关于 CUDA 的 NVIDIA 导师,我需要一些帮助。有如下代码:

//some includes
#define NUM_OF_ACCOMS 3360
#define SIZE_RING 16
#define NUM_OF_BIGRAMMS 256

//...some code...
    for (i = 1; i <= SIZE_RING; i++) {
        for (j = 1; j <= SIZE_RING; j++) {
            if (j == i) continue;
            for (k = 1; k <= SIZE_RING; k++) {
                if (k == j || k == i) continue;
                accoms_theta[indOfAccoms][0] = i - 1; accoms_theta[indOfAccoms][1] = j - 1; accoms_theta[indOfAccoms][2] = k - 1;
                accoms_thetaFix[indOfAccoms][0] = i - 1; accoms_thetaFix[indOfAccoms][1] = j - 1; accoms_thetaFix[indOfAccoms][2] = k - 1;
                results[indOfAccoms][0] = results[indOfAccoms][1] = results[indOfAccoms][2] = 0;
                indOfAccoms++;
            }
        }
    }   

    for (i = 0; i < SIZE_RING; i++)
        for (j = 0; j < SIZE_RING; j++) {
            bigramms[indOfBigramms][0] = i; bigramms[indOfBigramms][1] = j;
            indOfBigramms++;
        }
        for (i = 0; i < NUM_OF_ACCOMS; i++) {
            thetaArr[0] = accoms_theta[i][0]; thetaArr[1] = accoms_theta[i][1]; thetaArr[2] = accoms_theta[i][2];
            d0 = thetaArr[2] - thetaArr[1]; d1 = thetaArr[2] - thetaArr[0];
            if (d0 < 0)
                d0 += SIZE_RING;
            if (d1 < 0)
                d1 += SIZE_RING;
            for (j = 0; j < NUM_OF_ACCOMS; j++) {
                theta_fixArr[0] = accoms_thetaFix[j][0]; theta_fixArr[1] = accoms_thetaFix[j][1]; theta_fixArr[2] = accoms_thetaFix[j][2];
                d0_fix = theta_fixArr[2] - theta_fixArr[1]; d1_fix = theta_fixArr[2] - theta_fixArr[0];
                count = 0;
                if (d0_fix < 0)
                    d0_fix += SIZE_RING;
                if (d1_fix < 0)
                    d1_fix += SIZE_RING;
                for (k = 0; k < NUM_OF_BIGRAMMS; k++) {
                    diff0 = subst[(d0 + bigramms[k][0]) % SIZE_RING] - subst[bigramms[k][0]];
                    diff1 = subst[(d1 + bigramms[k][1]) % SIZE_RING] - subst[bigramms[k][1]];

                    if (diff0 < 0)
                        diff0 += SIZE_RING;
                    if (diff1 < 0)
                        diff1 += SIZE_RING;
                    if (diff0 == d0_fix && diff1 == d1_fix)
                        count++;
                }
                if (max < count) {
                    max = count;
                    results[indResults][0] = max; results[indResults][1] = i; results[indResults][2] = j;
                    count = 0;
                    indResults++;
                }
            }
        }

如您所见,ij 变量有两个主要循环。我需要来自accoms_theta 的foreach 数组检查来自accoms_thetaFix 的每个数组的条件。 (subst 是一个带有 SIZE_RING 元素的 int 数组)。那么你需要大约2^30 操作来检查所有数组。因为我是 CUDA 的新手,所以我需要一些帮助来并行化我的算法。

这是关于我的设备的一些信息

GeForce GT730M
Compute Capability 3.5
Global Memory 2 GB
Shared Memory Per Block 48 KB
Max Threads Per Block 1024
Number of multiprocessors 2
Max Threads Dim 1024 : 1024 : 64
Max Grid Dim 2*(10 ^ 9) : 65535 : 65535

【问题讨论】:

    标签: arrays parallel-processing cuda


    【解决方案1】:

    我不会详细介绍您尝试计算的任何内容,但我会就您可能会做什么提出建议。

    在 CUDA(或 OpenCL,甚至 OpenMP)中并行化串行算法的一种直接方法是“并行化循环”。在 CUDA 的上下文中,这意味着不是让单个线程迭代某个索引 i 的值,而是让不同的 GPU 线程处理 i 的不同值(或者 - 每几个 i 值一个线程)。

    这可以通过嵌套循环来完成,例如有两个索引 ij 对应于内核启动网格的两个维度。

    然而——“天真”地这样做只适用于embarrassingly parallel问题——每个线程计算/写入的数据之间没有依赖关系(例如ij的每个组合) )。此外,如果为不同的ij读取的数据重叠或交错,则需要额外注意防止重复读取相同的数据,从而降低性能。

    试试这个方法。如果它失败了,或者如果你得出它不适用的结论,请提出另一个问题 - 但在那个问题中,我们需要一个 Minimal, Complete, Verifiable Example - 你没有为这个问题提供它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 2017-05-20
      相关资源
      最近更新 更多