如何在GCC中手动调用libmvec函数处理__m128向量?
解决libmvec手动调用向量化函数的编译错误与函数名查询问题
编译标志补充
GCC 9.4.0要正确识别并链接libmvec的向量化函数,需要补充两个关键选项:
-mveclibabi=svml:指定采用SVML兼容的向量库ABI,这是libmvec要求的ABI格式-lmvec:显式链接libmvec库,仅用-lm无法关联到libmvec中的向量函数
保留你原有的优化和架构选项,完整编译命令应为:
gcc libmvectest.c -o libmvectest.bin -lm -lmvec -O3 -Wall -ffast-math -march=msse4 -mveclibabi=svml
另外,可通过ldd --version确认Ubuntu 20.04的glibc版本(默认版本已满足libmvec的依赖要求)。
正确查询libmvec函数名的方法
你尝试的_ZGVbN4ua16vl_cosf不符合当前环境的命名规则,推荐两种可靠的查询方式:
直接查看libmvec符号表
用nm工具列出libmvec中与cosf相关的符号:nm -D /usr/lib/x86_64-linux-gnu/libmvec.so | grep cosf输出中类似
_ZGVbN4v_cosf的符号,就是对应SSE4.1的4路单精度cos向量化函数。通过GCC自动向量化代码反查
写一段简单的循环代码,让GCC自动生成向量化调用,再从汇编文件中提取函数名:#include <math.h> void vec_cos(float *out, const float *in, int n) { for (int i = 0; i < n; i++) { out[i] = cosf(in[i]); } }编译生成汇编文件:
gcc -O3 -ffast-math -march=msse4 -mveclibabi=svml -S vec_cos.c打开生成的
vec_cos.s文件,就能找到GCC实际调用的libmvec函数名。
修正后的测试代码
为避免“隐式声明”错误,建议显式声明函数原型。下面是修正后的手动调用代码:
#include <stdio.h> #include <math.h> #include <immintrin.h> // 显式声明对应SSE4.1的4路单精度cos向量化函数 extern __m128 _ZGVbN4v_cosf(__m128); int main(int argc, char **argv) { float input = 0.1; float res[4]; __m128 m128 = _mm_set1_ps(input); __m128 cosm128 = _ZGVbN4v_cosf(m128); _mm_storeu_ps(res, cosm128); printf("%.8f %.8f\n", cosf(input), res[0]); }
用前面的完整编译命令编译即可正常运行。
内容的提问来源于stack exchange,提问作者Simon Goater
相关产品推荐
相关产品推荐

