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% медленнее, чем оригинальная версия.Поэтому я просто хочу дать компилятору дополнительную информацию.Таким образом, он может еще более эффективно векторизовать код.