Эффективное умножение матрицы 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, если вы не нацелены на очень экзотическую архитектуру, которая не поддерживается другими библиотеками.

Другие вопросы по тегам