为 CLANG 编译器提供循环长度断言

Iam*_*mIC 7 c++ simd clang compiler-optimization visual-c++

我有一个循环将两个float*数组加载到__m256向量中并处理它们。在这个循环之后,我有代码将平衡值加载到向量中,然后处理它们。所以函数上没有对齐要求。

以下是将数据余额加载到向量中的代码:

size_t constexpr            FLOATS_IN_M128              = sizeof(__m128) / sizeof(float);
size_t constexpr            FLOATS_IN_M256              = FLOATS_IN_M128 * 2;
Run Code Online (Sandbox Code Playgroud)

...

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]);    
Run Code Online (Sandbox Code Playgroud)

assert(bal < FLOATS_IN_M256);当我使用编译器资源管理器时,设置为“x86-64 clang 16.0.0 -march=x86-64-v3 -O3”,编译器会在该行存在时展开循环。但是,assert()在模式中被忽略RELEASE,这意味着循环不会被矢量化和展开。

为了测试,我定义了NDEBUG循环并将其矢量化并展开。

我尝试在适当的位置添加以下内容,但它们不起作用:

#pragma clang loop vectorize(enable)
#pragma unroll
#undef NDEBUG
Run Code Online (Sandbox Code Playgroud)

编译器应该能够从上面的代码片段之前的代码中看到这一点,bal < 8但事实并非如此。当不在DEBUG模式下时,我怎样才能告诉它这个断言是正确的?

Ran*_*its 6

您可以使用__builtin_assume向编译器提供代码中未明确显示的约束信息。这应该适用于gccclang

在发布的代码中,只需将 替换assert__builtin_assume(bal < FLOATS_IN_M256).