Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Алгоритмический конкурс - перемножение матриц


Автор: Zealint 8.2.2010, 18:54
Уважаемые программисты, предлагаю принять участие в моём алгоритмическом конкурсе. Требуется написать программу, которая перемножает две квадратные матрицы за минимальное время. Максимальный размер матриц - 5000x5000. Конкурс пока бесплатный, поэтому и приз не сильно большой - 1000 р. Описание правил приводится на моём сайте. http://zealint.ru/fast-matrix-multiplication-comp.html

В будущем я предполагаю проводить и другие конкурсы, сложнее и интереснее!

Удачи!

Автор: Фантом 8.2.2010, 19:52
Цитата(Zealint @  8.2.2010,  18:54 Найти цитируемый пост)
Уважаемые программисты, предлагаю принять участие в моём алгоритмическом конкурсе. 

Что-то условие какое-то нежизнеспособное.  smile Windows XP у меня под руками нет, да и машины с соответствующим процессором - тоже. Однако под Linux (конкретно openSuSE 11.2 x86-64) на одном ядре от Athlon X2 5200+ (в принципе, не мощнее, чем Ваш Intel Core 2 Duo 8400) вот эта вот тупейшая программа на Фортране
Код

program cross

  implicit none
  integer :: N
  integer(4), dimension(:,:),allocatable :: a,b,c

  open(1,file='data.dat')
  read(1,*) N
  
  allocate(a(N,N),b(N,N),c(N,N))    
 
  read(1,*) a
  read(1,*) b
  close(1)

  c=matmul(a,b)

  open(2,file='res.dat',status='replace')
  write(2,10) c

  close(2)
  deallocate(a,b,c)

10 format(5000(I7,2X))
end program cross

отработала за 145-150 секунд (плюс-минус пара секунд для разных запусков и матриц), в отличие от Ваших 800.  smile Если что - компилятор Intel'овский, вызывался ifort -fast cross.f90 -o cross, подсчет времени выполнялся с помощью банального time ./cross. Замена компилятора на Sun'овский привела к тому, что время счета увеличилось секунд на 20.

Это, собственно, к тому, что задача неудачная - такие вещи "убиваются" не алгоритмическими изысками, а просто правильным выбором инструмента. При этом попытки написать что-то более сложное, скорее всего, приведут в лучшем случае к повторению того же результата.

Автор: Zealint 8.2.2010, 20:29
Тов. Фантом, спасибо, что уделили внимание моему конкурсу. Дело в том, что создавая этот конкурс я, разумеется, подумал тех вещах, о которых вы говорите. Я бы не стал делать конкурс, если бы считал себя чайником : ). Я поставил в условиях Winsows XP, значит на то была определённая причина - это эксперимент, результаты которого мне интересны. Моя (та же самая) программа под Linux Enterprise с компилятором Intel C++ работает всего 108 секунд против ваших 145 (на процессоре, с частотой 2,67GHz). Да и то, программу я еще даже не начинал оптимизировать. Понимаете? В этом конкурсе я хочу, чтобы был именно Windows и хочу посмотреть, кто способен написать быструю программу под эту систему. Кстати, вы не написали, сколько ваша программа кушает памяти.

Попытки написать что-то более сложное должны привести к лучшему результату. Встроенным в язык программирования функциям я бы не стал доверять. Хотя, вдруг я не все такие функции пробовал? Кто знает... Но еще не было ни одного случая (какую бы я задачу не решал), чтобы встроенная в какую-либо библиотеку функция работала быстрее написанной руками реализации. Поэтому подборка инструментов, к сожалению, не даёт того, что мне нужно. Поэтому я и затеваю конкурсы.

Автор: Фантом 8.2.2010, 22:21
Цитата(Zealint @  8.2.2010,  20:29 Найти цитируемый пост)
Моя (та же самая) программа под Linux Enterprise с компилятором Intel C++ работает всего 108 секунд против ваших 145 (на процессоре, с частотой 2,67GHz).

Если процессор Intel, то это нормально. На моем AMD из icc можно будет выжать дополнительный десяток секунд, не больше. 

Цитата(Zealint @  8.2.2010,  20:29 Найти цитируемый пост)
В этом конкурсе я хочу, чтобы был именно Windows и хочу посмотреть, кто способен написать быструю программу под эту систему.

А смысл? Ни для каких практических целей программы такого рода под Windows никто писать не будет. Т.е. сама по себе задача, конечно, имеет право на существование, но в такой постановке ее результаты показывают непонятно что.

И, кстати, это в любом случае будет в основном соревнование компиляторов и библиотечных кодов.

Цитата(Zealint @  8.2.2010,  20:29 Найти цитируемый пост)
Кстати, вы не написали, сколько ваша программа кушает памяти.

Так ведь очевидно. Три матрицы 5000*5000 c 4-байтовыми элементами, все остальное - мелочь, не стоящая внимания. Получается что-то в районе 300 мегабайт (точнее, матрицам надо 286, по "честным" измерениям получается 288).

Цитата(Zealint @  8.2.2010,  20:29 Найти цитируемый пост)
Попытки написать что-то более сложное должны привести к лучшему результату.

Нет. В таких условиях все, что может дать реальный выигрыш - это блочные методы и аккуратное использование векторных возможностей процессоров. В тот же matmul оно уже заложено, так что удастся разве что немного подкорректировать параметры блоков, поиграв с укладкой их в кэш. Однако это имеет смысл для матриц фиксированного размера, т.е. именно 5000*5000 таким способом немного оптимизировать, возможно, и получится, а для произвольного размера больше времени уйдет на написание программы. smile

Цитата(Zealint @  8.2.2010,  20:29 Найти цитируемый пост)
Но еще не было ни одного случая (какую бы я задачу не решал), чтобы встроенная в какую-либо библиотеку функция работала быстрее написанной руками реализации. Поэтому подборка инструментов, к сожалению, не даёт того, что мне нужно. Поэтому я и затеваю конкурсы. 

В вычислительных задачах такая ситуация - редкое исключение из правил. По крайней мере до тех пор, пока считать надо что-то более-менее стандартное.

Автор: Zealint 9.2.2010, 07:33
Цитата

Если процессор Intel, то это нормально. На моем AMD из icc можно будет выжать дополнительный десяток секунд, не больше. 

Можно выжать больше, если вмешаться туда руками. Более того, я претендую на то, что моя программа под Windows скоро станет работать быстрее, чем ваша - под Linux. Этим вообще хочу показать, что ОС не играет сильной роли, если, конечно, не проводить какую-то совершенно жуткую оптимизацию.

Цитата

А смысл? Ни для каких практических целей программы такого рода под Windows никто писать не будет. Т.е. сама по себе задача, конечно, имеет право на существование, но в такой постановке ее результаты показывают непонятно что.

Результат будет показывать то, что мы можем выжать из Windows и Intel. Если проводить конкурсы для всех архитектур и ОС, то для этого у меня не хватит сил. На универсальном компьютере (архитектуры Intel, AMD или Mac) все равно результаты будут не слишком объективными, и вообще, если мне нужна будет совсем оптимальная программа, я задействую видеокарту, в которой будут вычисляться небольшие блоки, а большие будут считаться на обоих ядрах. Или вообще буду считать на кластере. То есть мне важна не сама скорость, с которой мы можем решать эту задачу, а скорость, которую можно выжать именно при моих ограничениях. Конечно, я могу такое же конкурс устроить и на Linux. Только мне сильно надоело наблюдать за тем, как программа скомпилированная на одном Линуксе соврешенно не хочет работать на другом. А в Windows XP хотя бы есть универсальность, которая нужна.

Цитата

Так ведь очевидно. Три матрицы 5000*5000 c 4-байтовыми элементами, все остальное - мелочь, не стоящая внимания. Получается что-то в районе 300 мегабайт (точнее, матрицам надо 286, по "честным" измерениям получается 288).

Не очевидно, я же не знаю что за алгоритм скрыт в матричном умножении. Если тупой тройной цикл, то понятно. У меня так же. Но у меня еще есть реализация одного из билинейных алгоритмов, которая требует еще около 10 матриц и в память не влезает. А мне нужно, чтобы влезала, поэтому я и провожу конкурс. 

Цитата

Нет. В таких условиях все, что может дать реальный выигрыш - это блочные методы и аккуратное использование векторных возможностей процессоров. В тот же matmul оно уже заложено, так что удастся разве что немного подкорректировать параметры блоков, поиграв с укладкой их в кэш. Однако это имеет смысл для матриц фиксированного размера, т.е. именно 5000*5000 таким способом немного оптимизировать, возможно, и получится, а для произвольного размера больше времени уйдет на написание программы

Так вот я вам обещаю, что ваш matmul будет повержен к концу конкурса. При одном условии - что люди начнут участвовать и начнётся конкуренция. Если конкуренции не будет, то, конечно, грустно. Значит народ не умеет программировать руками совсем, считая, что все уже есть в стандартных библиотеках. Это плохо. Еще раз: конкурс нужен для того, чтобы посмотреть, кто умеет программировать алгоритмы эффективно. Эффективность всегда достигается, когда учтена специфика задачи. В этом случае пасуют все встроенные алгоритмы, расчитанные на универсальный подход. 



Автор: Фантом 9.2.2010, 12:04
Цитата(Zealint @  9.2.2010,  07:33 Найти цитируемый пост)

Так вот я вам обещаю, что ваш matmul будет повержен к концу конкурса.

Ну хорошо. Когда кто-нибудь повергнет, напишите. Мне тоже интересно.  smile 

Автор: W4FhLF 9.2.2010, 12:50
Ну, господа, что-то слабенько. smile 

Intel Core 2 Duo P8400 2.2 Ггц:

Компилятор MSVC++ 2008:

Цитата

D:\R&D\matmul>matmul 1024
Strassen algorithm + SIMD
Matrices size:1024:1024 0.218 s.

Cycle unrolling + SIMD
Matrices size:1024:1024 0.39 s.


D:\R&D\matmul>matmul 2048
Strassen algorithm + SIMD
Matrices size:2048:2048 1.576 s.

Cycle unrolling + SIMD
Matrices size:2048:2048 4.041 s.


D:\R&D\matmul>matmul 4096
Strassen algorithm + SIMD
Matrices size:4096:4096 11.232 s.

Cycle unrolling + SIMD
Matrices size:4096:4096 33.493 s.


D:\R&D\matmul>matmul 5120
Strassen algorithm + SIMD
Matrices size:5120:5120 21.606 s.

Cycle unrolling + SIMD
Matrices size:5120:5120 64.241 s.


D:\R&D\matmul>



Компилятор Intel C++ 11 даёт такие же результаты с отличием в 1-2 секунды. 

Алгоритм Штрассена требует много памяти. Поэтому для матриц 5120х5120 используемая память достигает 900Мб. Но в рамках условий конкурса. smile Однако можно перемножать матрицы только кратные 2^n. Универсальный алгоритм работает в среднем в три раза хуже, однако его можно оптимизировать, чтобы он раза в два быстрее был.

Если бы можно было использовать GPU, то цифры были бы гораздо меньше. Перемножение 5000х5000 в рамках 8 секунд на обычной NVIDIA 9600GT реальная задача. 

Оптимизированное умножение (на у Фантома на фортране) у меня выполняется 187 сек.

Автор: Фантом 9.2.2010, 13:11
Цитата(W4FhLF @  9.2.2010,  12:50 Найти цитируемый пост)

Алгоритм Штрассена требует много памяти. Поэтому для матриц 5120х5120 используемая память достигает 900Мб. Но в рамках условий конкурса.

М-да, похоже, я ошибся, посчитав, что Штрассен в память не влезет. А код универсального варианта можно посмотреть? Хочется посмотреть на него в тех же условиях.

Автор: W4FhLF 9.2.2010, 13:22
Цитата(W4FhLF @  9.2.2010,  12:50 Найти цитируемый пост)
Универсальный алгоритм работает в среднем в три раза хуже, однако его можно оптимизировать, чтобы он раза в два быстрее был.


Я погорячился)

Цитата

Strassen algorithm + SIMD
Matrices size:5120:5120 20.67 s.

Cycle unrolling + pure SIMD + cache
Matrices size:5120:5120 41.434 s.

Cycle unrolling + SIMD
Matrices size:5120:5120 58.267 s.


Второй вариант не использует дополнительной памяти, но идёт более грамотная работа с память. Данные делятся на блоки относительно размера кеша и кеш-лайна. 


Автор: W4FhLF 9.2.2010, 13:41
Цитата(Фантом @  9.2.2010,  13:11 Найти цитируемый пост)
А код универсального варианта можно посмотреть? Хочется посмотреть на него в тех же условиях.


Не понял немного. В каких тех же? 

Автор: Фантом 9.2.2010, 13:45
Цитата(W4FhLF @  9.2.2010,  13:41 Найти цитируемый пост)

Не понял немного. В каких тех же?  

На той же машине, чтобы сравнить с тривиальным вариантом.

Автор: W4FhLF 9.2.2010, 14:06
Цитата(Фантом @  9.2.2010,  13:45 Найти цитируемый пост)
На той же машине, чтобы сравнить с тривиальным вариантом.


Тривиальный алгоритм с тремя циклами у меня работал больше 15 минут на матрицах 5120, я даже не дождался конца. smile
Слегка подправленный (скорее всего такой же как в фортране) с транспонированной второй матрицей работал 187 секунд. 

В аттчае вариант с двумя алгоритмами, которые я приводил в первом своём посте этой темы. 

Матрицы заполняются так:

Код

void matrix_fill(float *m, unsigned sz)
{
    for(int i = 0; i < sz*sz; ++i)
        m[i] = 1.0 / (i + 1);
}


запускать так:

Цитата

matmul_vc N


где N - размер матрицы. 

Чтобы выложить целиком, надо его доработать. 


Автор: Фантом 9.2.2010, 14:23
Цитата(W4FhLF @  9.2.2010,  14:06 Найти цитируемый пост)
запускать так:

Ну да, только exe-шник под Linux и запускать. smile Я исходники хочу (точнее, второй исходник - то, что метод Штрассена должен давать такие результаты, и так понятно).

Автор: Zealint 9.2.2010, 14:23




Цитата

Ну, господа, что-то слабенько.

Тов. W4FhLF, что вы меряетесь тут? Присылайте мне программу и я протестирую все на своей машине (по условию, я должен получить прогу на почту и чтобы она с файлами работала). Все сравнения будут объективными, и с кубической реализаций сравним, и со Штрассеном и с ним же в моем скромном исполнении, если кубический алгоритм я не смогу довести до победы. Кстати, у E8400 вы неправильно написали скорость, там 3000MHz. Давайте, участвуйте, посоревнуемся! Ваши "21s" меня приятно удивили, мне видимо придется долго думать, чтобы это переплюнуть. Еще дело в компиляторе...

Мне тяжеловато вести беседу на разных форумах, разные соображения можно у меня в блоге записывать... А лучше не записывать, а присылать программы. Тогда будет что с чем сравнивать.

Автор: Zealint 9.2.2010, 14:47
Цитата

Перемножение 5000х5000 в рамках 8 секунд на обычной NVIDIA 9600GT реальная задача. 

Конкурс на последовательную реализацию. Параллельные алгоритмы будут потом, причем задачи будут такие, что и 100 000 процессоров при кривых руках не помогут. И конкурсы на видеокарточке будут, но опять же - это сильно сужает круг участников. Сейчас-то никого нет, а если сказать, что видеокарта умеет считать - вообще все разбегутся. А когда я конкурс на кластере сделаю, там я один видимо и буду участвовать : ) Сейчас я специально простую задачу даю, или она сложная считается?

Автор: W4FhLF 9.2.2010, 15:03
Цитата(Zealint @  9.2.2010,  14:23 Найти цитируемый пост)
Кстати, у E8400 вы неправильно написали скорость, там 3000MHz.


У меня ноутбук. Там P8400 2.2 Ггц.

На данный момент все мои алгоритмы работают с матрицами кратными степеням двойки. Это противоречит условию конкурса, насколько я понимаю? 

Автор: Zealint 9.2.2010, 15:04
Цитата


запускать так:

matmul_vc N

где N - размер матрицы. 

Чтобы выложить целиком, надо его доработать.

Эта чудесная программа не запускается у меня. Пишет, что инструкция по адресу 0x004020С0 обратилась к памяти по адресу 0x00000000.

Вы там Release-опции не забыли добавить?

Добавлено через 3 минуты и 55 секунд
Цитата

У меня ноутбук. Там P8400 2.2 Ггц.

Точно, не разглядел...

Цитата

На данный момент все мои алгоритмы работают с матрицами кратными степеням двойки. Это противоречит условию конкурса, насколько я понимаю?

Почему противоречит? Никто вам не мешает делать с матрицей все что вздумается (например, дополнить нулями), главное, чтобы ответ был правильным. Но вы же понимаете, что неразумно матрицу порядка 5000 дополнять до 8192? Я же специально только 1Gb в условиях написал, чтобы это не работало. В рамках конкурса матрица может иметь совершенно произвольный размер от 1 до 5000. Конечно, чтобы выиграть, надо подумать, вы согласны?

Автор: W4FhLF 9.2.2010, 15:29
Цитата(Zealint @  9.2.2010,  15:04 Найти цитируемый пост)
Эта чудесная программа не запускается у меня. Пишет, что инструкция по адресу 0x004020С0 обратилась к памяти по адресу 0x00000000.


Какое N вы указали?


Цитата(Zealint @  9.2.2010,  15:04 Найти цитируемый пост)
Почему противоречит? Никто вам не мешает делать с матрицей все что вздумается (например, дополнить нулями), главное, чтобы ответ был правильным. Но вы же понимаете, что неразумно матрицу порядка 5000 дополнять до 8192?


Не совсем. Ближайшая граница, как вы могли заметить, это 5120. Хотя алгоритмы можно доработать. 

Автор: Zealint 9.2.2010, 17:01
Цитата

Какое N вы указали?

Чтобы вас не беспокоить, разобрался сам. Программа работает от 1024. А я указывал 10, 20 и т. д. : )
В любом случае надо чтобы работала для любого n причем именно так, как написано в правилах - ввод из файла и т. д. Проверять будет автоматическая система.


Цитата

Не совсем. Ближайшая граница, как вы могли заметить, это 5120. Хотя алгоритмы можно доработать.

Вот видите : ) всегда можно придумать хорошее число. Так я увижу ваш код у себя в ящике? Мне уже несколько человек обещали прислать программу, видимо еще пишут... Значит людям интересно. Любопытно мне, можно ли будет за две недели добиться результата, скажем 10 секунд... Я пока даже меньше 100 сделать не могу. Но думаю и сдаваться не собираюсь.

Автор: W4FhLF 9.2.2010, 17:23
Zealint, на днях я скину вам свой вариант. 

Автор: Pavia 10.2.2010, 22:31
Что мы можем? По моим расчетом для вашего 3ГГц придел порядка 10.41 с на вычисление.

Размер файла число не превышает 600 по модулю. 3 символа плюс пробел плюс "+" или  "-" итого 5 символов на число.
25 мегабайт на 5* на 2 матрицы 250 Мегабайт. Скорость чтения с HHD диска   и запись на нее составляет от 40 до 100 мб/с. 
C SSD больше. Раскошелитесь на покупку?
Во общем чтение + запись порядка 5-12 с как бы плюс еще столько.

Так как есть то что никто не знает можно посоревноваться. Но как заметили тут война компилятора против человека.

Автор: Zealint 11.2.2010, 08:43
Цитата

Что мы можем? По моим расчетом для вашего 3ГГц придел порядка 10.41 с на вычисление.


Почему?

Цитата

Размер файла число не превышает 600 по модулю. 3 символа плюс пробел плюс "+" или  "-" итого 5 символов на число.
25 мегабайт на 5* на 2 матрицы 250 Мегабайт. 

Ну да, правильно.

Цитата

Скорость чтения с HHD диска   и запись на нее составляет от 40 до 100 мб/с. 
C SSD больше. Раскошелитесь на покупку?

Нет, диск у меня один, поэтому все в равных условиях. Ну будет у всех быстрее на одинаковое время, ну и что?
Тут надо просто ручной ввод написать. Да и то на последней стадии оптимизации.

Цитата

Во общем чтение + запись порядка 5-12 с как бы плюс еще столько.

Верно. Но ручной ввод занимает около секунды.

Цитата

Так как есть то что никто не знает можно посоревноваться. Но как заметили тут война компилятора против человека.

Нет, тут война мозгов и реализаций. Конечно, компилятор тоже важен, но зачем с ним воевать?

Автор: Zealint 22.2.2010, 20:05
Конкурс завершён. http://zealint.ru/fast-matrix-multiplication-results.html подводятся итоги. Всем спасибо за участие!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)