c++ 给予CLANG编译器一个循环长度Assert

dwthyt8l  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(252)

我有一个循环,它将两个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是真的?

7vux5j2d

7vux5j2d1#

可以使用__builtin_assume为编译器给予代码中未显式显示的约束信息。这应该适用于gccclang
在发布的代码中,只需将assert替换为__builtin_assume(bal < FLOATS_IN_M256)

相关问题