Я хочу написать бенчмарк для Xeon Phi (60 ядер). В моей программе я использую стандарт OpenMP и встроенные функции Intel. Я реализовал параллельную версию алгоритма (5-точечное вычисление трафарета), которая быстрее в 230 раз, чем скалярный алгоритм. Я хочу добавить SIMD к параллельному коду. У меня проблемы с производительностью. Когда я вызываю _m512_store_pd (), производительность вычислений уменьшается, и параллельная версия с SIMD медленнее, чем версия без SIMD. В чем проблема? Что я должен сделать, чтобы получить лучшую производительность?
for(int i=start; i<stop; i+=threadsPerCore)
{
for(int j=8; j<n+8; j+=8)
{
__m512d v_c = _mm512_load_pd(&matrixIn[i * n_real + j]);
__m512d v_g = _mm512_load_pd(&matrixIn[(i - 1) * n_real + j]);
__m512d v_d = _mm512_load_pd(&matrixIn[(i + 1) * n_real + j]);
__m512d v_l = _mm512_loadu_pd(&matrixIn[i * n_real + (j - 1)]);
__m512d v_p = _mm512_loadu_pd(&matrixIn[i * n_real + (j + 1)]);
__m512d v_max = _mm512_max_pd(v_c, v_g);
v_max = _mm512_max_pd(v_max, v_d);
v_max = _mm512_max_pd(v_max, v_l);
v_max = _mm512_max_pd(v_max, v_p);
_mm512_store_pd(&matrixOut[i * n_real + j], v_max);
}
}
Я начинаю вычисления с 8, потому что у меня есть один вектор в начале и один вектор в конце, элементы гало. n_real — размер вектора -> n + 16. Вычисляются start и stop, так как я делю матрицу разбиения для 60 ядер, а opne-часть (m / 60) вычисляется четырьмя потоками HM.
Кто-то (возможно, вы), кажется, задал такой же вопрос (по крайней мере, приведенный пример кода такой же, как у вас) в Intel Developer Zone по адресу https://software.intel.com/en-us/forums/topic/531721 где есть ответы (в том числе переписать с 40% улучшением производительности).
Возможно чтение это было бы полезно?
(Если бы это был вы, я не вижу возражений спрашивать в обоих местах, но было бы вежливо сказать людям здесь, что вы уже спросили там, чтобы они не тратили время на воспроизведение ответов, которые люди уже дали в другом Форум).