MatLab: RAM access time
Mar. 18th, 2014 08:33 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Продолжаю копать недавний вопрос, довёл ситуацию до минимализма, и всё равно ничего не понимаю.
Есть некий скрипт, который выглядит примерно* так:
1. Запускаю его на своём компе — память загружена на некотором уровне X, процессор загружен на 25% (у меня 4 ядра, MatLab крутится на одном из них), время работы цикла 19 секунд.
2. Запускаю два MatLab, на каждом из них запускаю ручками копию этого скрипта. Память загружена вдвое больше (логично), процессор загружен на 50% (логично), время работы цикла 34 секунды (я ждал, очевидно, 19 секунд).
В чём фишка? Единственное разумное объяснение — меня ограничивает скорость чтения / записи RAM. В это не хочется верить, и как минимум хочется поверить.
Откуда следующие вопросы:
1. Как получить максимальную скорость чтения / записи RAM? Измерить / посчитать по техническим характеристикам / запустить утилиту.
2. Как посмотреть реальную скорость работы с RAM? В идеале иметь такой монитор, как Task Manager, который рисовал бы график в реальном времени, чтобы на нём глазами увидеть потолок, об который стучится мой процесс. Наш IT выслушал, попробовал две какие-то стандартные у них утилиты и развёл руками. Hotline MatLab вообще вопроса не понял (провёл с ними час по телефону, зол неописуемо).
3. (в голову как-то не лезет, что программу тормозит RAM, с детства привыкли, что у него скорость, конечно, ограниченная, но это только в теории) Какие ещё есть варианты объяснения этого эффекта?
*Скрипт выглядит «примерно» так, т.к. MatLab в принципе иногда работает с несколькими ядрами процессора. Например, простую операцию a + b он легко раскидывает на несколько ядер. А вот bsxfun(@plus, a, b), позволяющую складывать матрицы разного размера, уже не раскидывает. Поэтому для простоты я написал +, но на самом деле там bsxfun.
Есть некий скрипт, который выглядит примерно* так:
a = random(...); b = random(...); for i = 1 : 1000 a = a + b; end
1. Запускаю его на своём компе — память загружена на некотором уровне X, процессор загружен на 25% (у меня 4 ядра, MatLab крутится на одном из них), время работы цикла 19 секунд.
2. Запускаю два MatLab, на каждом из них запускаю ручками копию этого скрипта. Память загружена вдвое больше (логично), процессор загружен на 50% (логично), время работы цикла 34 секунды (я ждал, очевидно, 19 секунд).
В чём фишка? Единственное разумное объяснение — меня ограничивает скорость чтения / записи RAM. В это не хочется верить, и как минимум хочется поверить.
Откуда следующие вопросы:
1. Как получить максимальную скорость чтения / записи RAM? Измерить / посчитать по техническим характеристикам / запустить утилиту.
2. Как посмотреть реальную скорость работы с RAM? В идеале иметь такой монитор, как Task Manager, который рисовал бы график в реальном времени, чтобы на нём глазами увидеть потолок, об который стучится мой процесс. Наш IT выслушал, попробовал две какие-то стандартные у них утилиты и развёл руками. Hotline MatLab вообще вопроса не понял (провёл с ними час по телефону, зол неописуемо).
3. (в голову как-то не лезет, что программу тормозит RAM, с детства привыкли, что у него скорость, конечно, ограниченная, но это только в теории) Какие ещё есть варианты объяснения этого эффекта?
*Скрипт выглядит «примерно» так, т.к. MatLab в принципе иногда работает с несколькими ядрами процессора. Например, простую операцию a + b он легко раскидывает на несколько ядер. А вот bsxfun(@plus, a, b), позволяющую складывать матрицы разного размера, уже не раскидывает. Поэтому для простоты я написал +, но на самом деле там bsxfun.
no subject
Date: 2014-03-19 08:25 am (UTC)no subject
Date: 2014-03-19 05:20 pm (UTC)no subject
Date: 2014-03-19 05:39 pm (UTC)Тормозит не память, а кэш. Точнее, скорость памяти в данном случае не влияет, а размер кэша, вероятно, да.
Попробуй с матрицами меньшего размера, в 2 раза меньше, в 4 и т.п.
При работе с данными большого объема нужны другие алгоритмы. Простое разделение задачи на независимые части не поможет. Надо распараллеливать на более мелком уровне, например, распараллеливать сложение матриц. Вообще для матриц должен использоваться GPU, странно, что матлаб у тебя этого не делает (или делает?)
no subject
Date: 2014-03-20 08:26 am (UTC)no subject
Date: 2014-03-20 09:47 am (UTC)Еще я подумал, что матлаб может как-то ограничивать собственное потребление памяти и пытаться выбрасывать матрицы или части их на диск, или пытаться паковать матрицы. Проверить тут просто, надо удвоить размер матрицы и сравнить потребление памяти.
Но это все развлечение. На самом деле уже очевидно, что алгоритм твоей задачи (в данном случае - сложение матриц) надо менять, если ты хочешь ускорить процесс. Например, порезать матрицы на более мелкие, сложить их параллельно в разных копиях матлаба, затем склеить, т.е. примитивный map-reduce.
no subject
Date: 2014-03-20 01:15 pm (UTC)no subject
Date: 2014-03-20 01:19 pm (UTC)То есть (момент действительно для меня важный, поэтому лучше два раза его описать, чем один невнятно), если у меня скорость чтения, скажем, 100 единиц памяти в секунду, и именно эта величина ограничивает скорость моих расчётов, то, разрезав данные на 4 части, я получу 4 процесса, каждый из которых читает память со скоростью в 25 единиц в секунду, доводя память до предела скорости. Но в итоге у меня вычисления всё равно будут проходить со скоростью 100 единиц в секунду. Понимаешь? MathWorks не понял :-)
no subject
Date: 2014-03-20 01:29 pm (UTC)no subject
Date: 2014-03-20 01:39 pm (UTC)Не уверен, что у нас это будет реально. Это с тупым примером всё работает, а у меня с сотню разных операций, которые используют разные принципы. Каждая операция - примерно в таком вот духе, но рассчитывать на разумное использование кэша сложно даже если я оставлю всего одну строчку в матрице...
no subject
Date: 2014-03-20 04:24 pm (UTC)no subject
Date: 2014-03-20 04:50 pm (UTC)А параллельные вычисления каким образом? Потому что у каждого ядра своё кэш?
no subject
Date: 2014-03-20 09:26 pm (UTC)И очень часто это не реально.
no subject
Date: 2014-03-21 08:40 am (UTC)Это вечная проблема систем общего назначения, они более-менее справляются с простыми задачами и очень плохо со всякими специфичными.
no subject
Date: 2014-03-20 08:27 am (UTC)no subject
Date: 2014-03-20 09:22 am (UTC)Отсутствие (должной) загрузки процессора - основной признак взаимных блокировок.
Каждый матлаб ест свои 25% - блокировок нет.
И вообще, считать надо на GPU. На своих 4 процессорах ты ускоришь в лучшем случае в 4 раза.
На GPU у тебя в худьшем случае несколько сотен процессоров.
no subject
Date: 2014-03-20 09:36 am (UTC)no subject
Date: 2014-03-20 01:13 pm (UTC)no subject
Date: 2014-03-20 04:18 pm (UTC)Мы попробивали. Потом стали писать скриптовый язык, который бы автоматически код для GPU генерировал. (в качестве рекламы)
Потом переписали на скриптах все что было сделано руками.
Наш компилятор сам решает, что в GPU отдавать считать, а что сосчитать снаружи.
Но предметная область специфицеская.
Матрицы мы только допиливаем.
Есть общие библиотеки для питона для GPU.
no subject
Date: 2014-03-20 04:29 pm (UTC)Но даже на таком уровне у нас это нереально...