Эффективное умножение матрицы SSE NxN
Я пытаюсь реализовать SSE
версия большой матрицы с умножением матрицы. Я ищу эффективный алгоритм, основанный на SIMD
Реализации.
Мой желаемый метод выглядит так:
A(n x m) * B(m x k) = C(n x k)
И все матрицы считаются выровненными 16-байтовыми массивами с плавающей точкой.
Я искал в сети и нашел несколько статей, описывающих умножение 8x8 и даже меньше. Мне действительно нужно как можно более эффективно, и я не хочу использовать Eigen
библиотека или аналогичные библиотеки. (Только SSE3
чтобы быть более конкретным).
Поэтому я был бы признателен, если бы кто-нибудь мог помочь мне найти некоторые статьи или ресурсы о том, как начать реализовывать это.
1 ответ
Основной проблемой при реализации умножения матрицы на матрицу произвольного размера является не использование SIMD, а повторное использование кэшированных данных. Документ " Анатомия высокопроизводительного матричного умножения", составленный Гото и Ван де Гейном, является обязательным для прочтения, если вы хотите реализовать кешируемое умножение матриц-матриц, а также обсуждает выбор ядер для SIMD-совместимости. После прочтения этой статьи ожидайте достижения 50% машинного пика при умножении матрицы на матрицу после двух недель усилий.
Однако, если целью этой работы не является чистое обучение, я настоятельно рекомендую использовать высокооптимизированную библиотеку. На x86 лучше всего подходят OpenBLAS (BSD-лицензия, поддерживает динамическую диспетчеризацию процессора), BLIS (BSD-лицензия, легко переносимая на новые процессоры) и Intel MKL (коммерческая, поддерживает динамическую диспетчеризацию процессора на процессорах Intel). Из соображений производительности лучше избегать ATLAS, если вы не нацелены на очень экзотическую архитектуру, которая не поддерживается другими библиотеками.