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-18 07:37 pm (UTC)no subject
Date: 2014-03-18 09:12 pm (UTC)no subject
Date: 2014-03-18 09:20 pm (UTC)no subject
Date: 2014-03-19 11:59 am (UTC)Я не нашел простого способа мониторить пропускную способность памяти (есть такая штука как Intel Performance Counter Monitor которая интегрируется в виндовый Performance Monitor, но ее еще скомпилировать надо intel.ly/1i0zouv).
Попробуй уменьшить размер матриц, чтобы все три одновременно влезали в L2-кэш твоего проца. Учитывая, что весь L2-кэш делится между всеми ядрами. Если проблема в памяти, то в случае с двумя процессорами скорость параллельных вычислений должна возрасти. Хотя у тебя третья матрица в 1000 экземплярах создается - это может сбить оптимизатор кэша.
Проверь (в закладке Performance в Properties процесса в Process Explorer) не использует ли матлаб другие ресурсы кроме памяти и цпу.
no subject
Date: 2014-03-18 07:48 pm (UTC)Это у меня уже вечерний бред, на самом деле я в матлабе мало что понимаю, но R меня от циклов сильно отучил. Особенно там, где надо экономить ресурсы.
no subject
Date: 2014-03-18 09:14 pm (UTC)no subject
Date: 2014-03-18 08:09 pm (UTC)no subject
Date: 2014-03-18 09:15 pm (UTC)Тем не менее, есть какие-то методы проверки? Куда смотреть, чтобы понять, это блокировка или нет?
no subject
Date: 2014-03-19 09:25 am (UTC)Объяснением может быть то, что матлаб из рук вон плохо написан и опрашивает некий флаг в цикле вместо блокировки.
no subject
Date: 2014-03-19 05:21 pm (UTC)no subject
Date: 2014-03-18 08:54 pm (UTC)no subject
Date: 2014-03-18 09:17 pm (UTC)И у тебя есть какие-то сомнения в том, что они на разных ядрах сидят? У меня есть другие примеры, которые с меньшими объёмами данных работают, и они вполне параллелятся вручную, то есть я вижу не только загрузку процессора, но и выигрыш во времени. То есть, кажется, что они на разных ядрах.
no subject
Date: 2014-03-18 09:19 pm (UTC)A кто на каком ядре сидит... Это, знаешь ли, такие чудеса бывают. Скорее всего оба процесса сидят на всех ядрах сразу. по крайней мере у меня матлаб во времена оны сидел на всех доступных ядрах поровну.
no subject
Date: 2014-03-18 09:22 pm (UTC)2. Точно, у меня тоже сидит как бы на всех по чуть-чуть, но мне казалось, что это бага task manager’а :-)
no subject
Date: 2014-03-18 09:26 pm (UTC)И нет, не бага - точнее бага самих окошек.
и да, hyperthreading у тебя выключен? Боюсь тут оно как раз мешать будет
no subject
Date: 2014-03-18 09:37 pm (UTC)no subject
Date: 2014-03-19 05:40 pm (UTC)no subject
Date: 2014-03-19 06:07 pm (UTC)no subject
Date: 2014-03-20 07:24 am (UTC)no subject
Date: 2014-03-19 09:30 am (UTC)там же посмотреть, что процессор делает: в твоем коде он сидит (матлаба) или ос.
Конечно, конкретный процессор постоянно меняется. Это не должно иметь никакого влияния.
no subject
Date: 2014-03-18 09:19 pm (UTC)Может поможет page fault delta? Или что-нибудь еще из параметров памяти процесса. Process explorer немного лучше task manager.
no subject
Date: 2014-03-18 09:21 pm (UTC)Соответственно, и последнюю фразу я не понимаю. Объяснишь?
no subject
Date: 2014-03-18 09:27 pm (UTC)no subject
Date: 2014-03-18 09:33 pm (UTC)no subject
Date: 2014-03-18 09:49 pm (UTC)no subject
Date: 2014-03-18 09:51 pm (UTC)no subject
Date: 2014-03-19 07:02 am (UTC)http://searchitchannel.techtarget.com/feature/Windows-7-performance-monitoring-tools
Memory -> Cache faults/sec, например.
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)Но даже на таком уровне у нас это нереально...