gpt4 book ai didi

c++ - 提示编译器浮点 vector 计数可以被 8 整除?

转载 作者:行者123 更新时间:2023-12-02 03:02:58 27 4
gpt4 key购买 nike

static inline void R1_sub_R0(float *vec,  size_t cnt,  float toSubtract){
for(size_t i=0; cnt; ++i){
vec[i] -= toSubtract;
}
}

我知道 cnt 总是能被 8 整除,因此代码可以通过 SSE 和 AVX 进行矢量化。换句话说,我们可以将 *vec 作为 __m256 类型进行迭代。但编译器可能不知道这一点。 如何向编译器保证此计数能被 8 整除?

这样的事情会有帮助吗? (如果我们把它放在函数的开头)

assert(((cnt*sizeof(float)) % sizeof(__m256)) ==0 );  //checks that it's "multiple of __m256 type".

当然,我可以简单地将整个事情编写为矢量化代码:

static inline void R1_sub_R0(float *vec,  size_t cnt,  float toSubtract){
assert(cnt*sizeof(float) % sizeof(__m256) == 0);//check that it's "multiple of __m256 type".
assert(((uintptr_t)(const void *)(POINTER)) % (16) == 0);//assert that 'vec' is 16-byte aligned

__m256 sToSubtract = _mm256_set1_ps(toSubtract);
__m256 *sPtr = (__m256*)vec;
const __m256 *sEnd = (const __m256*)(vec+cnt);

for(sPtr; sPtr != sEnd; ++sPtr){
*sPtr = _mm256_sub_ps(*sPtr, sToSubtract);
}
}

但是,它的运行速度比原始版本慢 10%。所以我只想给编译器一些额外的信息。这样它就可以更有效地矢量化代码。

最佳答案

Hint the compiler that float-vector count is divisible by 8?

您可以通过嵌套另一个循环来半展开循环:

for(size_t i=0; i < cnt; i += 8){
for(size_t j=0; j < 8; j++){
vec[i + j] -= toSubtract;
}
}

编译器可以很容易地看到内部循环具有不断的迭代,并且可以展开它并可能使用 SIMD(如果它选择的话)。

Hint the compiler that float-vector count is [16-byte aligned]?

这有点棘手。

你可以使用类似的东西:

struct alignas(16) sse {
float arr[8];
};

// cnt is now number of structs which is 8th fraction of original cnt
R1_sub_R0(sse *vec, size_t cnt, float toSubtract) {
for(size_t i=0; i < cnt; i ++){
for(size_t j=0; j < 8; j++){
vec[i].arr[j] -= toSubtract;
}
}

除此之外,还有一些编译器扩展,例如__builtin_assume_aligned,可以与普通 float 组一起使用。

关于c++ - 提示编译器浮点 vector 计数可以被 8 整除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58117550/

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