我正在进行网络排序(对于小于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倍.