Загрузка в 256-битный регистр AVX2 из массива с заполнением 0 - PullRequest
1 голос
/ 22 января 2020

Я хочу загрузить 4 двойных в 256-битный регистр и дополнить нулями, если размер массива меньше 4.

register __m256d c = _mm256_loadu_pd(C);

Теперь предположим, что C содержит только три элемента, я хочу дополнить последнюю «запись» в регистре c до 0. Как я могу сделать это эффективно?

1 Ответ

0 голосов
/ 23 января 2020

Вот один из методов. В отличие от _mm256_maskload_pd, приведенная ниже функция не нуждается в загрузке или создании маски.

// Load 3 doubles from memory, zero out the 4-th one.
inline __m256d load3( const double* source )
{
    const __m128d low = _mm_loadu_pd( source );
    const __m128d high = _mm_load_sd( source + 2 );
    return _mm256_set_m128d( high, low );   // vinsertf128
}

Для полноты, вот еще 2 варианта.

// Zero out the high 2 double lanes.
inline __m256d zeroupper( __m128d low2 )
{
    const __m256d low = _mm256_castpd128_pd256( low2 ); // no instruction
    const __m256d zero = _mm256_setzero_pd();   // vxorpd
    // vblendpd is 4-5 times faster than vinsertf128
    return _mm256_blend_pd( zero, low, 3 ); // vblendpd
}
// Load 2 doubles from memory, zero out other 2
inline __m256d load2( const double* source )
{
    return zeroupper( _mm_loadu_pd( source ) );
}
// Load 1 double from memory, zero out the other 3
inline __m256d load1( const double* source )
{
    return zeroupper( _mm_load_sd( source ) );
}
...