gpt4 book ai didi

gcc - 为 GCC 的矢量扩展加载数据

转载 作者:行者123 更新时间:2023-12-04 08:53:05 26 4
gpt4 key购买 nike

GCC vector extensions提供一种不错的、合理的可移植方式来访问不同硬件架构上的一些 SIMD 指令,而无需求助于 hardware specific intrinsics (或自动矢量化)。

一个真正的用例是计算一个简单的附加校验和。尚不清楚的一件事是如何安全地将数据加载到向量中。

typedef char v16qi __attribute__ ((vector_size(16)));

static uint8_t checksum(uint8_t *buf, size_t size)
{
assert(size%16 == 0);
uint8_t sum = 0;

vec16qi vec = {0};
for (size_t i=0; i<(size/16); i++)
{
// XXX: Yuck! Is there a better way?
vec += *((v16qi*) buf+i*16);
}

// Sum up the vector
sum = vec[0] + vec[1] + vec[2] + vec[3] + vec[4] + vec[5] + vec[6] + vec[7] + vec[8] + vec[9] + vec[10] + vec[11] + vec[12] + vec[13] + vec[14] + vec[15];

return sum;
}

将指针转换到向量类型似乎有效,但我担心如果 SIMD 硬件期望向量类型正确对齐,这可能会以一种可怕的方式爆炸。

我想到的唯一其他选择是使用临时向量并显式加载值(通过 memcpy 或按元素分配),但在测试此抵消时,大部分加速都使用了 SIMD 指令。理想情况下,我认为这将类似于通用 __builtin_load()功能,但似乎不存在。

将数据加载到向量中可能会出现对齐问题的更安全方法是什么?

最佳答案

编辑 (感谢 Peter Cordes)您可以转换指针:

typedef char v16qi __attribute__ ((vector_size (16), aligned (16)));

v16qi vec = *(v16qi*)&buf[i]; // load
*(v16qi*)(buf + i) = vec; // store whole vector

这编译为 vmovdqa加载和 vmovups储藏。如果不知道数据是否对齐,请设置 aligned (1)生成 vmovdqu . ( godbolt )

请注意,还有几个用于加载和卸载这些寄存器的专用内置函数( Edit 2 ):
v16qi vec = _mm_loadu_si128((__m128i*)&buf[i]); // _mm_load_si128 for aligned
_mm_storeu_si128((__m128i*)&buf[i]), vec); // _mm_store_si128 for aligned

好像有必要用 -flax-vector-conversions出发地 char转至 v16qi有了这个功能。

另见: C - How to access elements of vector using GCC SSE vector extension
另见: SSE loading ints into __m128

(提示:谷歌最好的短语是“gcc loading __m128i”。)

关于gcc - 为 GCC 的矢量扩展加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9318115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com