Информация об изменениях

Сообщение Re[22]: .Net на эльбрусах от 19.08.2022 7:43

Изменено 19.08.2022 8:10 vdimas

Re[22]: .Net на эльбрусах
Здравствуйте, 4058, Вы писали:

4>Это показывает, что Intel выполняет этот тест в ~4 раза быстрее Эльбрус


Этот тест показывает, что авторы статьи не потрудились поискать наилучшую стратегию обхода памяти.
Вот наивная реализация умножения матриц:
for(i = 0 i < n; i++ )
 for(j = 0; j < n; j++ )
   for(k = 0; k < n; k++ )
     C[j * n + i] += A[j * n + k] * B[k * n + i];

Это схема ijk.
По классике наилучший результат из наивных даёт схема kji.
У авторов схема kij, которая, увы, является наихудшей.

Не наивной является схема прохода по транспонированной матрице.
Т.е одну из матриц сначала транспонируют, а потом в цикле нижнего уровня итерация проходит у всех трех матриц по 1-му элементу, а не прыгает как кенгуру по памяти.

Далее, операции j*n, i*n (для транспонированной) надо выносить наверх — компилятор С++ не имеет право выносить эти якобы константные для цикла нижнего уровня выражения выше по соображениям многопоточности — вдруг в параллельном потоке данные меняются, а мы и не знаем.
Увы, подобного рода оптимизации для Интела надо делать ручками.
И вот тут-то пресловутая автовекторизация SIMD и срабатывает, т.к. за один такт можно вычислить 4 ячейки, т.е. 4 оборота цикла.

А в Эльбрусе можно указать прагмами, что всё ОК, можно смело оптимизировать, будто это личные данные текущего потока.

Далее, обрати внимание на +=, уупс?
Надо заводить локальную переменную и накапливать результат в ней, а затем писать лишь однажды.

Ты дочитай до конца, автор там поиграл еще и получил на вручную написанной реализации результат примерно вдвое быстрее, чем с помощью EML, т.е. в 200 раз быстрее от исходного варианта.
А для Интел как ни крути — ничего уже особо не накрутишь.


4>при этом уступает в 20-ть раз тесту с использованием eml.


При этом eml ускорила наихудший вариант вычислений в 100 раз.


4>Это такая-же нелепость как сравнивать перемножение матриц с использованием SIMD и без него.


С чего ты решил, что SIMD не используется?
Компилятор компиллирует с SIMD инструкциями в любом случае.
Особенно хорошо для матриц.
Просто SIMD бывает очень разный.
Просто надо правильно обходить память, чтоы какие надо SIMD инструкции подставлялись.


4>В данном случае было бы интересно сравнить результаты с использованием упомянутого в статье MKL от Intel.


MKL даёт прирост от наихудшей наивной реализации в ~10 раз.
Сравни с ускорением в 200 раз на Эльбрусе.

В общем, у этой архитектуры есть характеристика — флопсы на такт.
Необходимо в реализации софта поднимать эту характеристику на максимум (т.е. загружать максимальное кол-во исполнительных блоков в каждом такте), чтобы Эльбрус показывал себя во всей красе.
Re[22]: .Net на эльбрусах
Здравствуйте, 4058, Вы писали:

4>Это показывает, что Intel выполняет этот тест в ~4 раза быстрее Эльбрус


Этот тест показывает, что авторы статьи не потрудились поискать наилучшую стратегию обхода памяти.
Вот наивная реализация умножения матриц:
for(i = 0 i < n; i++ )
 for(j = 0; j < n; j++ )
   for(k = 0; k < n; k++ )
     C[j * n + i] += A[j * n + k] * B[k * n + i];

Это схема ijk.
По классике наилучший результат из наивных даёт схема kji.
У авторов схема kij, которая, увы, является наихудшей.

Не наивной является схема прохода по транспонированной матрице.
Т.е одну из матриц сначала транспонируют, а потом в цикле нижнего уровня итерация проходит у всех трех матриц по 1-му элементу, а не прыгает как кенгуру по памяти.

Далее, операции j*n, i*n (для транспонированной) надо выносить наверх, и вот тут-то пресловутая автовекторизация SIMD и срабатывает, т.к. за один такт можно вычислить 4 ячейки, т.е. 4 оборота цикла.

Далее, обрати внимание на +=.
Надо заводить локальную переменную и накапливать результат в ней, а затем писать лишь однажды.

Ты дочитай до конца, автор там поиграл еще и получил на вручную написанной реализации результат примерно вдвое быстрее, чем с помощью EML, т.е. в 200 раз быстрее от исходного варианта.
А для Интел как ни крути — ничего уже особо не накрутишь.


4>при этом уступает в 20-ть раз тесту с использованием eml.


При этом eml ускорила наихудший вариант вычислений в 100 раз.


4>Это такая-же нелепость как сравнивать перемножение матриц с использованием SIMD и без него.


С чего ты решил, что SIMD не используется?
Компилятор компиллирует с SIMD инструкциями в любом случае.
Особенно хорошо для матриц.
Просто SIMD бывает очень разный.
Просто надо правильно обходить память и раскручивать циклы, чтобы какие надо SIMD инструкции подставлялись.


4>В данном случае было бы интересно сравнить результаты с использованием упомянутого в статье MKL от Intel.


MKL даёт прирост от наихудшей наивной реализации в ~10 раз.
Сравни с ускорением в 200 раз на Эльбрусе.

В общем, у этой архитектуры есть характеристика — флопсы на такт.
Необходимо в реализации софта поднимать эту характеристику на максимум (т.е. загружать максимальное кол-во исполнительных блоков в каждом такте), чтобы Эльбрус показывал себя во всей красе.

Капризная штука, да? ))
Компилятор надо развивать нон-стоп, ес-но, на него вся надежда.

Но что здесь внушает оптимизм — при улучшении компилятора можно перепрогонять им софт и получать профит, не меняя ни исходники, ни железо.