Результаты тестирования Intel Xeon Phi 7210 - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь разобраться в результатах тестирования процессора Intel Xeon Phi 7210. Моя настройка и вопрос:

Теоретическая пиковая производительность на Intel Xeon Phi:

64 (ядра) x 2 (блоки AVX512) x 16 (32-битное с плавающей запятой) x 1,3 ГГц = 2662,4 Гфлопс / сек.

Настройка: матричное умножение 2 матриц 512x512 с использованием типов данных __mm512

Результаты:

Arrangement                 Time, ms            GB/s         GFLOP/s
OMP threads                    0.620           5.075         432.616  (#pragma omp parallel for above the outer loop) 
Tiling(using tasks)            3.680           0.855          72.873    (creating task for each 32x32 tile of output matrix)

GFlops: N N N [умножения] + N * N * (N-1) [сложения]

ГБ / с: sizeof (float) * 3 * (N * N ) т.е. 2 матрицы чтения и 1 запись. В моем случае N = 512

Вывод подтвержден и корректен, однако я кое-что не понимаю. Это далеко не теоретическая скорость, несмотря на использование 512-битных регистров и даже развертывание самого внутреннего l oop (вторая матрица также переносится для увеличения пространственной локальности). Я ожидал, что Tiling будет работать намного лучше, так как я спроектировал размер плитки таким образом, чтобы все частичные плитки полностью помещались в кэш данных 32 КБ, но это медленно.

Мои вопросы:

1: как я могу узнать, сколько ядер или потоков используется моей программой?

2: могу ли я выполнять контролируемое выполнение в потоках, например, выполнение 64 потоков, но на 64 ядрах (с использованием 1 аппаратного потока на ядро ​​или, возможно, максимум 2 аппаратных потока, поскольку в каждом ядре есть два модуля AVX512)

3: как лучше всего использовать 6 портов памяти? Теоретическая пропускная способность составляет 100+ ГБ / с, и моя - лишь часть этого. Я развернул внутреннее большинство l oop дважды, т.е. есть 4 следующих

   __m512 vx0 = _mm512_load_ps((P*)&in1[(i*M1Rdim)+(k+0)]);  //loads up 16 floats into a __m512
   __m512 vy0 = _mm512_load_ps((P*)&in2[(j*M1Cdim)+(k+0)]);  //loads up 16 floats into a __m512
...