我有一个循环,它将两个float*
数组加载到__m256
向量中并处理它们。在这个循环之后,我有代码将值的平衡加载到向量中,然后处理它们。因此,对函数没有对齐要求。
下面是将数据余额加载到向量中的代码:
size_t constexpr FLOATS_IN_M128 = sizeof(__m128) / sizeof(float);
size_t constexpr FLOATS_IN_M256 = FLOATS_IN_M128 * 2;
...
assert(bal < FLOATS_IN_M256);
float ary[FLOATS_IN_M256 * 2];
auto v256f_q = _mm256_setzero_ps();
_mm256_storeu_ps(ary, v256f_q);
_mm256_storeu_ps(&ary[FLOATS_IN_M256], v256f_q);
float *dest = ary;
size_t offset{};
while (bal--)
{
dest[offset] = p_q_n[pos];
dest[offset + FLOATS_IN_M256] = p_val_n[pos];
offset++;
pos++;
}
// the two vectors that will be processed
v256f_q = _mm256_loadu_ps(ary);
v256f_val = _mm256_loadu_ps(&ary[FLOATS_IN_M256]);
当我使用编译器资源管理器时,设置为“x86-64 clang 16.0.0 -march=x86-64-v3 -O3”,编译器在assert(bal < FLOATS_IN_M256);
行存在时展开循环。但是,在RELEASE
模式下,assert()
被忽略,这意味着循环不会被向量化和展开。
为了测试,我定义了NDEBUG
,并将循环向量化和展开。
我尝试在适当的地方添加以下内容,但它们不起作用:
#pragma clang loop vectorize(enable)
#pragma unroll
#undef NDEBUG
编译器应该能够从上面的代码片段之前的代码中看到bal < 8
,但它没有。在不处于DEBUG
模式时,我如何告诉它这个Assert是真的?
1条答案
按热度按时间7vux5j2d1#
可以使用
__builtin_assume
为编译器给予代码中未显式显示的约束信息。这应该适用于gcc
和clang
。在发布的代码中,只需将
assert
替换为__builtin_assume(bal < FLOATS_IN_M256)
。