使用OpenMP在C中并行化基数排序

时间:2015-03-04 20:50:37

标签: c sorting parallel-processing openmp radix-sort

您如何在C中使用OpenMP并行化基数排序算法?

我的程序是对典型基数排序的修改:它根据数字的二进制表示对整数数组进行排序,您可以在其中改变应解释为一位数的位数(这基本上将用于根据整数的大小来获得不同的运行时间。)

我有一个带有三个参数的基数函数:

// n is the number of elements in data
// b is number of bits that should be interpreted as one digit
void radix(int* data, int n, int b);

此外,我的基数函数以b增量遍历所有位(int:32位):

for(bit = 0; bit < 32; bit += b) { ... }

其中包含三个部分:

  • 计算某个数字(实际是位)的出现次数,以确定存储桶需要多少存储空间。 bucket[(data[i] >> bit) & (int)(pow(2,b)-1)]++
  • 将值放入临时数组(存储桶)。

    bitval = (data[i] >> bit) & (int)(pow(2,b)-1)

    temp_data[bucket[bitval]++] = data[i]

  • 将临时存储区中的值复制到指定给函数的*data指针。

    for(i = 0; i < n; i++) { data[i] = temp_data[i] }

1 个答案:

答案 0 :(得分:0)

并行化将成为一个问题,因为限制因素将是内存带宽(CPU开销非常小,只有一个内存总线)。

也不是使用浮点函数pow(2,b),而是根据b创建位掩码和右移计数:

    numberOfBits = b;
    shiftCount = 0;
    while(1){  // main loop
        // set numberOfBuckets
        numberOfBuckets = 1 << numberOfBits;
        bitMask = numberOfBuckets - 1;
        // code to generate histogram for this field goes here
        // ...
        shiftCount += numberOfBits;
        // check for partial bit field
        if((shiftCount + numberOfBits) > (8*sizeof(unsigned int))){
            numberOfBits = (8*sizeof(unsigned int)) - shiftCount;
            shiftCount = (8*sizeof(unsigned int)) - numberOfBits;
            continue; // do partial bit field
        }
        // check for done
        if(shiftCount == (8*sizeof(unsigned int)))
            break; // done
    }

如果对有符号整数进行排序,则需要调整最重要的字段(对于有符号整数,算术右移也取决于编译器/平台)。一个解决方案(对于二进制补码有符号整数)是转换为无符号整数,并补充用于存储桶索引生成的符号位。