如果有人对排序网络对 32 位整数的 64 个元素序列的适用性问题感兴趣(我曾经),我自己看了一眼,发现以下内容:
- qsort 每个序列大约需要 2600ns
- std::sort 每个序列大约需要 1100 ns
- Bose-Nelson 排序网络每个序列大约需要 1200 ns
- Batcher 奇偶网络每个序列大约需要 850ns
- 使用 AVX2 指令同时处理 8 个序列的 Batcher 奇偶网络每个序列耗时 70ns
序列是统一生成的,因此熵最大,即最坏情况,有利于排序网络。
您可能期望使用 AVX2 理论上可以实现 8 倍的加速,为什么会有 12 倍的加速?查看程序集,Clang 以如下块执行排序网络的多次交换:
00007FF6DA081374 vpminsd ymm4,ymm0,ymm1
00007FF6DA081379 vpmaxsd ymm0,ymm0,ymm1
00007FF6DA08137E vpminsd ymm1,ymm2,ymm3
00007FF6DA081383 vpmaxsd ymm2,ymm2,ymm3
00007FF6DA081388 vpminsd ymm3,ymm4,ymm1
00007FF6DA08138D vpmaxsd ymm1,ymm4,ymm1
00007FF6DA081392 vpminsd ymm4,ymm0,ymm2
00007FF6DA081397 vpmaxsd ymm0,ymm0,ymm2
00007FF6DA08139C vpminsd ymm2,ymm4,ymm1
00007FF6DA0813A1 vpmaxsd ymm1,ymm4,ymm1
而标量代码使用 cmp、cmovgt、cmovlt 指令,这些指令也与 mov 和来自内存的指令混合在一起。随心所欲。
我使用自己的实现和基准测试代码用于 Batcher 奇数/偶数网络,地址为 https://github.com/jamesthomasgriffin/sorting_networks,对于 Bose-Nelson 网络,https://github.com/Vectorized/Static-Sort。