Авто-векторизация скалярного произведения в цикле

Я пытаюсь автоматически векторизовать следующий цикл. В следующем цикле мы i- а также j-Зациклите нижний треугольник матрицы. К сожалению, отчет о векторизации не может векторизовать (= преобразовать в инструкции AVX SIMD) j- и k-петли. Но я думаю, что это просто, потому что нет псевдонимов указателей (#pragma ivdep и вариант компилятора -D NOALIAS) и данные (массив x: 1D и массив p: 1D) выровнены до 64 байтов.

Может быть, что if— это проблема, но даже с ifБез решения (дорогостоящая операция сдвига и подсчет знака двойника) компилятор не может векторизовать этот цикл.

__assume_aligned(x, 64);
__assume_aligned(p, 64);
#pragma omp parallel for simd reduction(+:accum)
for ( int i = 1 ; i < N ; i++ ){ // loop over lower triangle (i,j), OpenMP SIMD LOOP WAS VECTORIZED
for ( int j = 0 ; j < i ; j++ ){ // <-- remark #25460: No loop optimizations reported
double __attribute__((aligned(64))) scalarp = 0.0;
#pragma omp simd
for ( int k=0 ; k < D ; k++ ){ // <-- remark #25460: No loop optimizations reported
// scalar product of \sum_k x_{i,k} \cdot x_{j,k}
scalarp += x[i*D + k] * x[j*D + k];
}

// Alternative to following if:
// accum +=  - ( (long long) floor( - ( scalarp + p[i] + p[j] ) ) >> 63);
#pragma ivdep
if ( scalarp + p[i] + p[j] >= 0 ){ // check if condition is satisfied
accum += 1;
}
}
}

Относится ли это к проблеме, что начальные точки OpenMP для каждого потока OpenMP не известны до времени выполнения? Я думал, что это решает simd и Intel векторизация знает об этом.

Компилятор Intel: 18.0.2 20180210

редактировать: я посмотрел на сборку, и теперь ясно, что код уже векторизован, извините за то, что все вас ограничивают.

0

Решение

Просмотр сборки действительно помогает. Код уже векторизован. OpenMP SIMD LOOP WAS VECTORIZED также заботится о внутренней петле в этом конкретном случае.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector