Ответ от @stevengj в той же ветке Discourse:
Правильно ли я считаю, что ускорение происходит из-за того, что память выровнена более благоприятным образом для всего, что угодно dgemv_ делает, когда он находится в режиме trans = T ?
Закрыть.Это связано с памятью, но речь идет о locality , а не о выравнивании.Основная вещь, которую нужно понять, это то, что более эффективно получать доступ к последовательным (или, по крайней мере, поблизости) данным из памяти, чем к данным, которые разделены, из-за существования строк кэша .(Последовательный доступ также имеет некоторые преимущества при использовании SIMD инструкций.)
Юлия хранит матрицы в мажорном порядке столбцов , так что столбцы непрерывны в памяти.Следовательно, когда вы умножаете транспонированную матрицу (которая не была скопирована) на вектор, она может вычислить ее как произведение точек смежного столбца (= транспонированная строка) на смежный вектор, который имеет хороший пространственная локальность и, следовательно, эффективно использует строки кэша.
Для умножения не -транспонированной матрицы на вектор, напротив, вы берете точечные произведения несмежные строки матрицы с вектором, и сложнее эффективно использовать строки кэша.Я полагаю, что для улучшения пространственной локальности оптимизированный BLAS, такой как OpenBLAS, фактически вычисляет точечные произведения нескольких строк за раз («блок») с вектором - поэтому он всего на 10% медленнее и не намного хуже.(Фактически, даже транспонированный случай может сделать некоторую блокировку, чтобы сохранить вектор в кэше.)