GCC中__builtin_vectorelements的替代方案及C2y向量扩展应用
GCC中__builtin_vectorelements的替代方案
在GCC中,vec_countof可以直接作为__builtin_vectorelements的替代方案。
适配LLVM与GCC的SIMD向量类型定义(array.h)
通过预处理器定义通用的向量/数组类型,同时兼容LLVM和GCC的SIMD扩展:
#ifndef ARRAY_H #define ARRAY_H #ifdef __clang__ #define arr(T, N) T __attribute__((ext_vector_type(N))) #define vec(T, N) T __attribute__((ext_vector_type(N))) #define vectorelements(V) __builtin_vectorelements(V) #else #define arr(T, N) T[N] #define vec(T, N) T __attribute__((vector_size(sizeof(T)*N))) #define vectorelements(V) vec_countof(V) #endif #endif // ARRAY_H
点积、叉积实现示例(dotcross.c)
以下示例展示如何使用上述类型实现任意类型与长度的点积、叉积运算:
#include "array.h" #include <stdio.h> // 点积实现 #define dot_product(A, B) ({ \ typeof(A) _a = (A); \ typeof(B) _b = (B); \ typeof(_a[0]) _sum = 0; \ for (int i = 0; i < vectorelements(_a); i++) { \ _sum += _a[i] * _b[i]; \ } \ _sum; \ }) // 3维叉积实现 #define cross_product_3d(A, B) ({ \ typeof(A) _a = (A); \ typeof(B) _b = (B); \ typeof(_a) _res; \ _res[0] = _a[1]*_b[2] - _a[2]*_b[1]; \ _res[1] = _a[2]*_b[0] - _a[0]*_b[2]; \ _res[2] = _a[0]*_b[1] - _a[1]*_b[0]; \ _res; \ }) int main() { // 测试float类型4维点积 vec(float, 4) v1 = {1.0f, 2.0f, 3.0f, 4.0f}; vec(float, 4) v2 = {5.0f, 6.0f, 7.0f, 8.0f}; float dot = dot_product(v1, v2); printf("4维float点积结果: %.2f\n", dot); // 测试int类型3维叉积 vec(int, 3) v3 = {1, 2, 3}; vec(int, 3) v4 = {4, 5, 6}; vec(int, 3) cross = cross_product_3d(v3, v4); printf("3维int叉积结果: [%d, %d, %d]\n", cross[0], cross[1], cross[2]); return 0; }
编译命令
- GCC编译:
gcc -O2 -march=native dotcross.c -o dotcross_gcc
- Clang编译:
clang -O2 -march=native dotcross.c -o dotcross_clang
运行输出
4维float点积结果: 70.00 3维int叉积结果: [-3, 6, -3]
内容的提问来源于stack exchange,提问作者Jon Daniel
相关产品推荐
相关产品推荐

