c – 并行化小型网络排序

我正在进行网络排序(对于小于8的数组),并注意到所有算法都关注其允许并行操作的能力.这是一个大小为5的数组.

 #define SWAP(x,y) if (data[y] < data[x]) { int tmp = data[x]; data[x] = data[y]; data[y] = tmp; }

    //Parallelizable
    SWAP(1, 2);
    SWAP(4, 5);

    //Parallelizable
    SWAP(0, 2);
    SWAP(3, 5);

    //Parallelizable
    SWAP(0, 1);
    SWAP(3, 4);
    SWAP(2, 5);

    //Parallelizable
    SWAP(0, 3);
    SWAP(1, 4);

    //Parallelizable
    SWAP(2, 4);
    SWAP(1, 3);

    //Parallelizable
    SWAP(2, 3);

我正在使用long int数组(因此每个元素的大小为8个字节).那么有什么简单的方法可以在C中并行化这些操作吗?是否有任何硬件特定命令可用于实现此目的(SIMD,ASM(x86)等)

最佳答案 正如
this answer对有关排序小集合的问题所解释的那样,通过将其定义更改为以下定义,您实际上可以使交换代码更具性能:

#define SWAP(x, y) {                        \
    int dx = data[x];                       \
    data[x] = dx < data[y] ? dx : data[y];  \
    data[y] ^= dx ^ data[x];                \
}

根据研究论文Applying Sorting Networks to Synthesize Optimized Sorting Libraries,这个版本的SWAP是无分支的,并且可以编译为GCC或Clang上仅有5个指令,具有良好的优化级别.该文章还暗示了这样一个事实,即指令数量较少可能实际上使代码受益于指令级并行性.

如果xor不适用于要排序的类型,则可以使用另一个版本的SWAP,该版本使用两个条件而不是一个,这应该与xor版本一样快.实际上,我在我的一个排序库中使用这个技巧,并且在排序网络中排序一个小的固定大小的整数集合,从“插入排序不比插入排序更好”到“插入排序快几倍”,当我介绍这个技巧时.对排序网络排序8个整数的集合比在我的计算机上排序排序快5倍.

点赞