1

我一直在尝试在支持 AVX512 的机器上以及之前为 AVX2 优化过的代码上使用 _mm256_popcnt_epi64。

不幸的是,我遇到了找不到该功能的问题。然而,找到了相应的__m512i等价物。该__m256i功能是否已弃用?

4

1 回答 1

2

_mm512_popcnt_epi64AVX512-VPOPCNTDQ 的一部分。256 位和 128 位版本还需要 AVX512VL 才能使用具有 128 位或 256 位向量的 AVX512 指令。

主流的AVX512 CPU都有AVX512-VL。Xeon Phi CPU 没有 AVX512-VL。

_mm512_popcnt_epi8并且 Epi16 在 Ice Lake 中也是新的,作为AVX512-BITALG 的一部分)

也许您忘记启用必要的编译器选项(如 GCC-march=native以启用您正在编译的机器可以执行的所有操作),或者您正在为一个不具备这两种功能的目标进行编译。如果是这样,那么编译器将没有_m256_popcnt_epi64作为内在函数的定义,因此在 C 中它将假定它的和未声明的函数并发出对它的调用。(在链接时当然不会找到。)和/或它会警告或错误(C 或 C++)关于未找到原型。

目前很少有 CPU 具有 AVX512-VPOPCNTDQ维基百科 AVX512 功能与 CPU 矩阵):

  • Knight's Mill(最后一代至强融核):只有 AVX512-VPOPCNTDQ,没有 AVX512VL,也没有 BITALG。所以只有__m512i版本可用于gcc -O3 -march=knm. 您绝对应该在 Xeon Phi 上使用 512 位向量,除非数据布局适用于 256 位并且需要对 512 位进行额外的洗牌。但是请注意,对于某些没有 512 位版本的 AVX / AVX2 指令,它的速度很慢,例如元素小于 32 位的随机播放。(无 AVX512 BW)

  • Ice Lake / Tiger Lake:具有 AVX512 VPOPCNTDQ、BITALG 和 AVX512 VL,因此_mm256_popcnt_epi64epi8为此目标微架构编译时受支持,例如gcc -O3 -march=icelake-client. (假设你的编译器的头文件是正确的)。

    GCC8.3 及更早版本有一个错误,其中-march=icelake-client/icelake-server不启用-mavx512vpopcntdq. (GCC7 不知道-march=icelake-client)。它在 GCC8.4 中已修复,因此要么升级到最新的 GCC8,要么更好地升级到最新的稳定版 GCC;几年的开发通常应该有助于 GCC 使用新的 ISA 扩展(如 AVX-512)制作更好的代码,尤其是使用掩码寄存器。或者只是手动使用-march=icelake-client -mavx512vpopcntdq; 确实有效:https ://godbolt.org/z/a7bhcjdhr


在 Ice Lake 上选择 256 位和 512 位向量是一种权衡,就像在 Skylake-x 上一样:当 512 位向量微指令在运行时,端口 1 上的向量 ALU 不会被使用。并且最大涡轮时钟速度可能会降低。 SIMD 指令降低 CPU 频率。因此,如果您没有从更宽的向量中获得太多加速(例如,由于内存瓶颈,或者您的 SIMD 循环只是较大程序的一小部分),那么在一个循环中使用 512 位向量可能会损害整体性能。

但请注意,Icelake 客户端 CPU 并没有受到太大影响,而且我不确定vpopcnt指令是否算作“重”,如果在客户端 CPU 上完全没有降低最大 turbo 的话,我也不确定。大多数整数 SIMD 指令都不算数。请参阅有关LLVM [X86] Prefer 512-bit vectors on Ice/Rocket/TigerLake (PR48336)的讨论。不过,在 512 位微指令运行时,端口 1 的矢量 ALU 部分仍然关闭。


其他 CPU 根本没有硬件 SIMD popcnt 支持,也没有_mm512_popcnt_epi64可用的形式。

即使您只有 AVX2,根本没有 AVX512,SIMD popcnt 也比popcnt现代 CPU 上的非小型阵列具有快速vpshufb( _mm256_shuffle_epi8) 优势。 https://github.com/WojciechMula/sse-popcount/有用于 Harley-Seal 累积的 AVX2 和 AVX512 版本,vpternlogd以减少用于 popcounting 的 SIMD LUT 查找量。

同样在 Stack Overflow Counting 1 bits (population count) on large data using AVX-512 or AVX-2显示了几年前从该仓库复制的一些代码。

如果您需要单独计算单独元素的计数,只需使用标准解包来支持vpshufbvpsadbw反对零向量以将 hsum 转换为 64 位 qword 块。

如果您需要位置 popcount(每个位位置的单独总和),请参阅https://github.com/mklarqvist/positional-popcount

于 2020-05-18T23:53:18.533 回答