Я хочу, чтобы векторизовать умножение двух массивов с выравниванием по памяти. Я не нашел способ размножить 64 * 64 бит в AVX/AVX2, поэтому я просто сделал цикл-разворот и загрузил/хранилища AVX2. Есть ли более быстрый способ сделать это?
Примечание. Я не хочу сохранять результат с половиной результата каждого умножения.
void multiply_vex(long *Gi_vec, long q, long *Gj_vec){
int i;
__m256i data_j, data_i;
__uint64_t *ptr_J = (__uint64_t*)&data_j;
__uint64_t *ptr_I = (__uint64_t*)&data_i;
for (i=0; i<BASE_VEX_STOP; i+=4) {
data_i = _mm256_load_si256((__m256i*)&Gi_vec[i]);
data_j = _mm256_load_si256((__m256i*)&Gj_vec[i]);
ptr_I[0] -= ptr_J[0] * q;
ptr_I[1] -= ptr_J[1] * q;
ptr_I[2] -= ptr_J[2] * q;
ptr_I[3] -= ptr_J[3] * q;
_mm256_store_si256((__m256i*)&Gi_vec[i], data_i);
}
for (; i<BASE_DIMENSION; i++)
Gi_vec[i] -= Gj_vec[i] * q;
}
UPDATE:
Я использую микроархитектуру Haswell с компиляторами ICC/GCC. Таким образом, оба AVX и AVX2 в порядке.
Я заменяю -=
на C intrisic _mm256_sub_epi64
после цикла размножения умножения, где он получает некоторое ускорение. В настоящее время это ptr_J[0] *= q; ...
Я использую __uint64_t
, но является ошибкой. Правильный тип данных __int64_t
.