Comments 15
Монументальный труд, спасибо! Есть же люди, которым не лень учить других!
Вопрос: а если я использую NumPy, там всё эффективно реализовано?
Наблюдаются странности со временем выполнения при размерностях матриц, равных степени двойки.
А на маке есть инструменты, позволяющие замерить доступы/миссы по кешам (типа perf в Linux)? Есть подозрение, что при "круглых" размерах разные доступы попадают в один и тот же set кеша и ассоциативности не хватает, чтобы разрулить конфликты - но это только предположение, детально код не смотрел и в любом случае при возможности лучше явно измерить.
Главный инструмент в macOS для оценки производительности Xcode Instruments, но у меня с ним как-то раньше не задалось. Надо бы протестить, но код из статьи только с целью разобраться, что да как устроено и понять насколько код написанный "на коленке" хуже чем то, что реализовано производителем в BLAS. Так что результат меня устраивает и больше тратить время на эту задачу не хочется)
Вот это статья, так статья. Статьища! Хабр - торт
Подскажите, "заполненные матрицы" в большинстве мест в статье и "плотные матрицы" в одном из заголовков ("Базовый вариант умножения плотных матриц") - это же синонимы? Это два варианта перевода dense matrix?
Спасибо за статью, было интересно прочитать. Ранее в рамках интереса выполнял похожую задачу с разницей того, что это всё не на CPU а на GPU используя OpenCL/CUDA. Если кому-то интересно, исследовательскую работу провел товарищ из Европы - https://cnugteren.github.io/tutorial/pages/page1.html
Потрясающая статья, большое спасибо. На Apple M4 10 core такие циферки при первом запуске:
Start ZIG MM mult benchmark f32
----------------------------
M = 3000, N = 3000, K = 4000, NB = 96, NTHREADS = 1
----------------------------
V00 check = 9002396026.1525, time = 22.491209 GF/sec = 2.98
V01 check = 9002396026.1525, time = 2.228460 GF/sec = 30.09
ARM sme exampl check = 9002396026.1352, time = 0.296731 GF/sec = 225.98
V02 sme check = 9002396026.1352, time = 0.416260 GF/sec = 161.09
V03 SME+L1L2 check = 9002396026.1352, time = 0.161521 GF/sec = 415.15
V04 SME+L1L2x2 check = 9002396026.1352, time = 0.086962 GF/sec = 771.09
V05 SME+L1L2x4 check = 9002396026.1352, time = 0.050918 GF/sec = 1316.92
V06 SME+MAX check = 9002396026.1352, time = 0.054740 GF/sec = 1224.97
--------------
Apple BLAS check = 9002396026.1352, time = 0.046933 GF/sec = 1428.74
Спасибо за тест, рад, что все работает!
Результаты совпадают с тем, что выдает мой:
Start ZIG MM mult benchmark f32
----------------------------
M = 3000, N = 3000, K = 4000, NB = 96, NTHREADS = 1
----------------------------
V00 check = 8998229076.8414, time = 22.893146 GF/sec = 2.93
V01 check = 8998229076.8414, time = 2.212305 GF/sec = 30.31
ARM sme exampl check = 8998229076.8095, time = 0.291058 GF/sec = 230.38
V02 sme check = 8998229076.8095, time = 0.418173 GF/sec = 160.35
V03 SME+L1L2 check = 8998229076.8095, time = 0.167515 GF/sec = 400.29
V04 SME+L1L2x2 check = 8998229076.8095, time = 0.089717 GF/sec = 747.41
V05 SME+L1L2x4 check = 8998229076.8095, time = 0.050723 GF/sec = 1321.98
V06 SME+MAX check = 8998229076.8095, time = 0.052684 GF/sec = 1272.78
--------------
Apple BLAS check = 8998229076.8095, time = 0.045733 GF/sec = 1466.22Запустите еще, пожалуйста, с параметром --nt=4 и --nt=10
zig build --release=fast run -- --m=3000 --n=3000 --k=4000 --nt=4
zig build --release=fast run -- --m=3000 --n=3000 --k=4000 --nt=10При N=4096 падение производительности относительно N=4095 и N=4097 составляет 2.5 раза, при этом функции от Apple работают стабильно, то есть это известная проблема, и у неё есть решение.
Если у кого-то есть понимание или предположения, с чем это связано, пожалуйста, поделитесь в комментариях.
На такое может влиять ассоциативность кэша. При размере кратном степени двойки начало строки матрицы будет отображаться всего на несколько линий кэша.
Умножение матриц: пример использования расширения ARM SME2 в Apple M4 Pro