Pull to refresh

Comments 15

Монументальный труд, спасибо! Есть же люди, которым не лень учить других!

Вопрос: а если я использую NumPy, там всё эффективно реализовано?

numpy при сборке ищет BLAS/LAPACK. Если Apple BLAS найдётся при сборке, то будет эффективно.

В miniconda, кажись, numpy собран с openblas, а там есть реализация с использованием ARM SME2, так что должно работать, но я не проверял.

Наблюдаются странности со временем выполнения при размерностях матриц, равных степени двойки.

А на маке есть инструменты, позволяющие замерить доступы/миссы по кешам (типа perf в Linux)? Есть подозрение, что при "круглых" размерах разные доступы попадают в один и тот же set кеша и ассоциативности не хватает, чтобы разрулить конфликты - но это только предположение, детально код не смотрел и в любом случае при возможности лучше явно измерить.

Главный инструмент в macOS для оценки производительности Xcode Instruments, но у меня с ним как-то раньше не задалось. Надо бы протестить, но код из статьи только с целью разобраться, что да как устроено и понять насколько код написанный "на коленке" хуже чем то, что реализовано производителем в BLAS. Так что результат меня устраивает и больше тратить время на эту задачу не хочется)

Вот это статья, так статья. Статьища! Хабр - торт

Подскажите, "заполненные матрицы" в большинстве мест в статье и "плотные матрицы" в одном из заголовков ("Базовый вариант умножения плотных матриц") - это же синонимы? Это два варианта перевода dense matrix?

Да, все верно, я приводил к единообразию, но похоже что-то пропустил

Спасибо за статью, было интересно прочитать. Ранее в рамках интереса выполнял похожую задачу с разницей того, что это всё не на CPU а на GPU используя OpenCL/CUDA. Если кому-то интересно, исследовательскую работу провел товарищ из Европы - https://cnugteren.github.io/tutorial/pages/page1.html

Большая была разница в производительности между CUDA и OpenCL?

Потрясающая статья, большое спасибо. На 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 работают стабильно, то есть это известная проблема, и у неё есть решение.
Если у кого-то есть понимание или предположения, с чем это связано, пожалуйста, поделитесь в комментариях.

На такое может влиять ассоциативность кэша. При размере кратном степени двойки начало строки матрицы будет отображаться всего на несколько линий кэша.

Спасибо за наводку, почитаю про это

Sign up to leave a comment.

Articles