Я использую этот код:Когда (если когда-либо) я должен сказать R параллельно, чтобы не использовать все ядра?
library(parallel)
cl <- makeCluster(detectCores() - 1)
clusterCall(cl, function(){library(imager)})
то у меня есть функция упаковщик ищет что-то вроде этого:
d <- matrix #Loading a batch of data into a matrix
res <- parApply(cl, d, 1, FUN, ...)
# Upload `res` somewhere
я тестировал на моем ноутбуке, с 8 ядрами (4 ядра, гиперпотоковой) , Когда я запустил его на 50 000 строк, 800 столбцов, матрицу, потребовалось 177,5 с, и большую часть времени 7 ядер поддерживали почти на 100% (по словам сверху), то он сидел там в течение последних 15 или так секунд, что, я думаю, сочетало результаты. Согласно system.time()
, пользовательское время составляло 14 секунд, чтобы совпадало.
Теперь я работаю на EC2, 36-ядерный c4.8xlarge, и я вижу, что он проводит почти все свое время только с одним ядром на 100%. Точнее: происходит примерно 10-20 секунд, когда используются все ядра, то около 90 секунд всего одного ядра на 100% (используется R), затем около 45 секунд другого материала (где я сохраняю результаты и загрузите следующую партию данных). Я делаю партии из 40 000 строк, 800 столбцов.
Долгосрочная средняя нагрузка, согласно сверху, колеблется около 5,00.
Это кажется разумным? Или существует точка, в которой R-параллелизм тратит больше времени на коммуникационные издержки, и я должен ограничивать, например, 16 ядер. Здесь есть какие-либо эмпирические правила?
Ссылка: CPU spec Я использую «Linux 4.4.5-15.26.amzn1.x86_64 (amd64)». R 3.2.2 (2015-08-14)
ОБНОВЛЕНИЕ: Я пробовал с 16 ядрами. Для наименьших данных время выполнения увеличилось с 13,9 до 18,3 с. Для средних данных:
With 16 cores:
user system elapsed
30.424 0.580 60.034
With 35 cores:
user system elapsed
30.220 0.604 54.395
I.e. накладные расходы часть занимала такое же количество времени, но параллельный бит имел меньше ядер, поэтому потребовалось больше времени, и поэтому потребовалось больше времени в целом.
Я также пробовал использовать mclapply()
, как это предлагается в комментариях. Казалось, что это немного быстрее (примерно 330 против 360-х годов по конкретным тестовым данным, которые я пробовал), но это было на моем ноутбуке, где другие процессы или перегрев могут повлиять на результаты. Итак, я пока не делаю никаких выводов.
Это зависит от конкретной используемой функции и от того, сколько данных необходимо скопировать для каждой задачи. Как правило, накладные расходы на параллелизацию не должны сильно зависеть от количества ядер. – Roland
@Roland. Это зависит, по крайней мере, линейно от количества ядер, а в более сложных схемах параллелизации зависимость может быть даже суперлинейной IIRC. –
@KonradRudolph Спасибо. Однако обычно это должно быть компенсировано временем, сохраненным за счет использования большего количества ядер (по крайней мере, при сравнении от 16 до 36 ядер). Если это не так, OP, вероятно, копирует большие объекты в рабочие и из рабочих. – Roland