在 OSX 10.14.5 上安装 clickhouse-cityhash 时缺少指令 `_mm_crc32_u64`

Missing instruction `_mm_crc32_u64` when installing clickhouse-cityhash on OSX 10.14.5

我正在尝试在 OSX 10.14.5 上使用 pip 安装 clickhouse-cityhash,但它失败并显示以下(删节)输出:

src/city.cc:396:5: error: use of undeclared identifier '_mm_crc32_u64'
    CHUNK(1, 1); CHUNK(k0, 0);
    ^
...
fatal error: too many errors emitted, stopping now [-ferror-limit=]
  20 errors generated.
  error: command 'cc' failed with exit status 1

我也尝试通过 CC=gccCC=g++ 进行编译,但无济于事。

失败时 运行 的命令是:

cc -fno-strict-aliasing -fno-common \
   -dynamic -g -Os -pipe -fno-common \
   -fno-strict-aliasing -fwrapv -DENABLE_DTRACE \
   -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes \
   -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall \
   -Wstrict-prototypes -DENABLE_DTRACE -arch i386 \
   -arch x86_64 -pipe -Iinclude \
   -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 \
   -c src/city.cc -o build/temp.macosx-10.14-intel-2.7/src/city.o \
   -O3 -msse4.2 -Wno-unused-value -Wno-unused-function

在我试图理解问题的过程中,我查看了 source code,我可以看到对 _mm_crc32_u64 的四个调用构成了错误中提到的 CHUNK 预处理器指令的一部分日志:

f = _mm_crc32_u64(f, a);                                    \
g = _mm_crc32_u64(g, b);                                    \
h = _mm_crc32_u64(h, c);                                    \
i = _mm_crc32_u64(i, d);                                    \
j = _mm_crc32_u64(j, e);                                    \

我在 Intel Intrinsics Guide 中找到了对 _mm_crc32_u64 的引用,所以我的理解是它是作为 C 函数的英特尔内部指令,是 SSE4.2 指令集的一部分。

我认为我的机器不包含 SSE4.2 指令集,但是当我 运行 以下命令时:

sysctl -a | grep cpu.features

SSE4.2 包含在列表中:

machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 PCLMULQDQ DTES64 MON DSCPL VMX SMX EST TM2 SSSE3 FMA CX16 TPR PDCM SSE4.1 SSE4.2 x2APIC MOVBE POPCNT AES PCID XSAVE OSXSAVE SEGLIM64 TSCTMR AVX1.0 RDRAND F16C

因此,我是否应该期望 _mm_crc32_u64 可用?如果是,出现此错误的可能原因是什么?

如果没有,我可以做些什么来使这些说明可用?

非常感谢@PeterCordes 在上述问题评论中提出的非常宝贵的意见!


pip install clickhouse-cityhash 期间失败的构建命令包含 -arch i386 标志。尽管存在此标志,x86 clang 的默认行为是构建 64 位代码。

但是,这似乎不是 Apple clang 的默认行为。如果生成 32 位代码,则 _mm_crc32_u32 将是可用的最大 CRC,这意味着 _mm_crc32_u64 未定义。

因此,一种解决方案是不使用 Apple clang。

大多数使用 OSX 的开发人员都会熟悉 brew 包管理器并安装它。您可能会发现您已经通过 brew 安装了一个版本的 gcc 作为另一个包的依赖项。

检查以下内容:

brew list | grep gcc

如果没有,请安装:

brew install gcc

可执行文件应该在您的 $PATH(通常在 /usr/local/bin)中作为 gcc 或类似的可用——我的可执行文件作为 gcc-8.

可用

要使用,只需定义要与 CC envvar 和 运行 pip install 一起使用的 gcc;例如:

CC=gcc-8 pip install clickhouse-cityhash

希望这对您有所帮助:)