2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: Перемножение матриц в С++
Сообщение15.06.2017, 23:03 
Заслуженный участник


20/08/14
11182
Россия, Москва
Может и не всегда, однако в большинстве случаев. И проигрыш от 30% до 12% (в умножении) несравним с проигрышем в 10-15 раз - и это после неслабых усилий по оптимизации.
Потому, если надо "ехать", то выгоднее применить библиотеку, которая почти гарантированно выдаст далеко не худший результат в любых условиях, чем писать что-то своё и долго потом оптимизировать и адаптировать под разные внешние условия. Пусть даже результат библиотеки будет и не 100% оптимальным - ради этого оптимума придётся потратить месяцы (а то и годы) труда. Имхо.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение15.06.2017, 23:22 


15/06/17

10
Dmitriy40
Да я не против: просто хотел подчеркнуть, что планка высших достижений иногда неподвластна даже очень сильным коллективам, которым безусловно является Intel, теоретическую поддержку которому оказывает нехилый профессорский коллектив ученых. И потом, для алгоритмов диагонализации упакованных матриц разность достигает более 50-ти процентов. И не надо хватать звезды с неба, чтобы реализовать довольно примитивный алгоритм перемножения матриц, уступающий в скорости dgemm Intel MKL всего процентов 30.
Что касается Relatively Robust Representations алгоритма, то разрыв достигает 2000%!

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 00:19 
Заслуженный участник


20/08/14
11182
Россия, Москва
YYSS
Да я тоже не против.
К тому же здесь речь шла лишь об умножении матриц.
Кстати у меня вот пока (со вчерашнего дня) не получилось догнать MKL даже близко, никак не придумаю как "кормить" fmadd команды с темпом 16 double чисел за такт и при этом не проседать из-за ассоциативности кэша. Асимптотика показывает (уже раз 100 пересчитывал в разных вариантах) что это реально, надо лишь правильно сделать разбиение задачи. Так что правы когда говорят что это хороший учебный пример на многостадийную оптимизацию кода, я уже насчитал полдесятка методов ускорения, а до пиковой скорости ещё далеко. Так что насчёт звёзд с неба Вы чуток погорячились думаю, не так всё просто. Подсматривать же в чужом коде неспортивно/неинтересно. :-)
На этой оптимистичной ноте можно пожалуй и закончить отступление.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 00:20 
Заслуженный участник
Аватара пользователя


01/09/13
4321
Dmitriy40 в сообщении #1225844 писал(а):
библиотеку Intel MKL даже близко не догнали по скорости

Если я правильно помню, эта библиотека оптимизирована под архитектурные особенности одноимённых процессоров...

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 00:28 
Заслуженный участник


20/08/14
11182
Россия, Москва
Geen
Я не уверен точно т.к. не смотрел её, но из очевидных соображений думаю она или сама подстраивается в момент выполнения под текущий процессор, или тип процессора задаётся ключами компилятору (вероятней всего). И да, разумеется оптимизирована. Ещё встречал утверждения что на процессорах AMD она вовсе не такая быстрая даже по сравнению с аналогами.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 01:45 


15/06/17

10
Geen в сообщении #1225922 писал(а):
Если я правильно помню, эта библиотека оптимизирована под архитектурные особенности одноимённых процессоров...

Совершенно верно: она определяет тип процессора (интеловского!) и подставляет соответствующий код: именно поэтому dgemm Intel MKL таких агромадных размеров, исчисляющихся мегабайтами.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 02:23 
Аватара пользователя


07/02/12
1403
Питер
Dmitriy40 в сообщении #1225920 писал(а):
не проседать из-за ассоциативности кэша

Может, все-таки всю матрицу стоит повернуть :-) ? Или хотя бы пачку столбцов так, что б шириной с линейку кеша получилось.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 04:30 
Заслуженный участник


20/08/14
11182
Россия, Москва
bondkim137 в сообщении #1225965 писал(а):
Может, все-таки всю матрицу стоит повернуть :-) ? Или хотя бы пачку столбцов так, что б шириной с линейку кеша получилось.
Это разные практически независимые оптимизации. И поворот всей матрицы или только текущего столбца (группы столбцов) эквиваленты.
Чтобы снизить трафик памяти надо в кэше перемножать кусочки матриц не менее 128х128, а ассоциативность кэша всего 8, поэтому вероятно надо перемножать неквадратный блок, типа 8х2048, что может быть больше самой матрицы ... В общем хорошая задачка на организацию потоков данных с учётом возможностей аппаратуры.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 09:45 
Аватара пользователя


31/10/08
1244
Я бы тоже транспонировал.
Есть быстрый код, для 4х4
http://masm32.com/board/index.php?PHPSE ... 6#msg65026
И как пишут для любого размера.
http://masm32.com/board/index.php?topic=6140.0

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 10:08 


15/06/17

10
Dmitriy40 в сообщении #1225920 писал(а):
YYSS
К тому же здесь речь шла лишь об умножении матриц.

Дело в том, что умножении матриц играет важную вспомогательную роль во многих ключевых алгоритмах линейной алгебры, например, в диагонализации, интернетные примеры для которой я и привел. Т.е. нет скорости умножения матриц - нет скорости и соответствующего алгоритма. Хотя в моих ссылках можно еще много чего интересного найти, касающегося проколов Intel MKL в их, как они рекламируют, самых быстрых алгоритмах.

Pavia
Есть такая программа: PC GAMESS. В ней есть ссылка на ассемблерный код, который содержит и быстрое перемножение матриц, не уступающее по скорости dgemm Intel MKL.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 10:51 
Аватара пользователя


31/10/08
1244
YYSS
Я тут посмотрел http://eigen.tuxfamily.org/ она на Си++ но оптимизирована и под SSE, AVX, CUDA и NEON.
Там и перемножение и транспонирование есть, не надо голову ломать.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 14:55 


07/10/15

2400
Для интереса привожу код, который работает быстрее чем с транспонированием,
правда не намного, но тем не менее (800 мс против 1100 мс)
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
int jj,kk,i;
   int nb=100;
   
   for (jj=0; jj<NStr; jj=jj+nb)
   for (ii=0; ii<NStr; ii=ii+nb)
   for (j=jj; j<jj+nb; j++)
   for (i=ii; i<ii+nb; i++)
       *(D+i+j*NStr)=0;
   
   for (kk=0; kk<NStr; kk=kk+nb)
   for (jj=0; jj<NStr; jj=jj+nb)
   for (ii=0; ii<NStr; ii=ii+nb)
       
   for (k=kk; k<kk+nb; k++)    
   for (j=jj; j<jj+nb; j++)
   for (i=ii; i<ii+nb; i++)
       
        *(D+i+j*NStr)+=*(B+i+k*NStr)**(M+k+j*NStr);
 


тут видимо блоки 100х100, из за частого обращения к ним помещается в кэш и там уже всё работает быстрее,
кстати если одну из матриц дополнительно транспонировать, то получается только медленнее

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 19:34 
Аватара пользователя


07/02/12
1403
Питер
Что бы был толк от транспонирования, следует понимать, из-за чего, собственно, этот толк должен возникать. А для начала можно и более грубые артифакты поправить, перечитав несколько сообщений вверх.

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение16.06.2017, 21:17 


07/10/15

2400
Там не менее следующий код работает в 1.5 раза медленнее предыдущего (и это не считая накладных расходов на транспонирование)

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
 int jj,kk,i;
   int nb=100;
   
   for (jj=0; jj<NStr; jj=jj+nb)
   for (ii=0; ii<NStr; ii=ii+nb)
   for (j=jj; j<jj+nb; j++)
   for (i=ii; i<ii+nb; i++)
       *(D+i+j*NStr)=0;
   
   
   
   for (ii=0; ii<NStr; ii=ii+nb)
   for (jj=0; jj<NStr; jj=jj+nb)    
   for (kk=0; kk<NStr; kk=kk+nb)
       
   for (i=ii; i<ii+nb; i++)    
   for (j=jj; j<jj+nb; j++)
   { val=0;
   for (k=kk; k<kk+nb; k++)
       val+=*(BT+k+i*NStr)**(M+k+j*NStr);
       *(D+i+j*NStr)=val;
   }
 


так, что предыдущий код самый быстрый из того что получилось

 Профиль  
                  
 
 Re: Перемножение матриц в С++
Сообщение17.06.2017, 08:24 


15/06/17

10
Andrey_Kireew

Советую вам ознакомиться с основами оптимизации циклов здесь.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 64 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: HungryLion


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group