【问题标题】:Parallelizing a code with dependency并行化具有依赖关系的代码
【发布时间】:2016-08-12 19:26:39
【问题描述】:

我的代码如下:

数组a 包含有关其元素所属组的信息。即元素i 属于组a[i]。每个组可以包含两个元素。我想将此信息存储在 b 中,其长度为 2*number 组。所以,b[j]b[j+1] 的值会给我属于组 j/2(整数除法)和 j 的元素是偶数。

void assign(int *a, int *b){
    for(int i = 0; i<N; i++){
        int group = a[i];
        int posit=2*group;
        if(b[2*i]!=0){
            posit++;
        }
        b[posit] = i;
    }
}

N as is clear length of a.

b[] 中的默认值为零,表示没有元素。

有明确的数据依赖性,并行化看起来并不容易。我正在寻找进一步的建议,如果我缺少一种聪明的方法。

【问题讨论】:

    标签: parallel-processing cuda openmp hpc


    【解决方案1】:

    一般来说,您可以尝试在包含对 {i, a[i]} 的数组上简单地使用并行排序算法。也许有一个更快的通用方法,我目前没有看到......

    然而,特别是在 CUDA 中,您可以利用这样一个事实,即当您有 2 个冲突的线程将 32 位字写入同一内​​存位置时——一个保证成功(尽管您不知道是哪一个)。形式上,它充当Arbitrary CRCW 机器。

    因此,您可以在 2 个内核调用中解决您的问题:

    __global__ void assign1(int* a, int* b, int elementCount) {
        int idx = threadIdx.x + blockIdx.x*blockDim.x;
        if (idx<elementCount) {
            int group = a[idx];
            b[2*group] = idx;
        }
    }
    
    __global__ void assign2(int* a, int* b, int elementCount) {
        int idx = threadIdx.x + blockIdx.x*blockDim.x;
        if (idx<elementCount) {
            int group = a[idx];
            if (b[2*group] != idx)
                b[2*group+1] = idx;
        }
    }
    
    __host__ void assign(int* dev_a, int* dev_b, int elementCount) {
        int gridSize = elementCount/512+1;
        int blockSize = 512;
        assign1<<<gridSize,blockSize>>>(dev_a, dev_b, elementCount);
        assign2<<<gridSize,blockSize>>>(dev_a, dev_b, elementCount);
    }
    

    assign1 中,最多 2 个线程写入同一内​​存位置 b[2*group]。这些线程之一保证成功。在assign2 中,写入失败的线程使用b[2*group+1] 重复该过程。

    如果组中最多有 3 或 4 个元素,则可以重复此方法,但随着数量的增加,它很快就会变得不可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多