2015-03-10 3 views
1

Я потратил немало времени на переписывание своего кода, чтобы использовать больше ядер, но когда я сравнивал его, я обнаружил, что все, что я достиг, делал это в 7 раз медленнее исходного кода, несмотря на то, что он работает на 16 ядрах, а не на одном! Это заставляет меня думать, что я должен делать что-то неправильно.Многопроцессорность медленнее, чем последовательная с python

Код 4000+ строк и требует много довольно тяжелых входных файлов, поэтому я не собираюсь публиковать что-то, что воспроизводит проблему. Однако я могу сказать, что функция, которую я вызываю, обычно занимает 0,1 с для запуска и вызывает некоторые библиотеки c с использованием ctypes. Кроме того, в память поступает довольно много данных - возможно, 1 МБ? Некоторые псевдо-код, который выглядит как медленный бит:

def AnalyseSection(Args): 
     Sectionsi,SectionNo,ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq=Args 
     for i in range(len(Sections[Elements])): 
      #Do some heavy lifting with ctypes 
     return Result 

    for i in range(10): 
     for j in range(10): 
      for k in range(10): 
       Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList] 
       pool=mp.Pool(processes=NoCPUs,maxtasksperchild=1) 
       result = pool.map(AnalyseSection,Args) 
       pool.close() 
       pool.join() 

Я надеялся, что кто-то мог заметить очевидную ошибку, которая вызывает его работать так гораздо медленнее? Для выполнения функции требуется некоторое время (обычно 0,1 с для каждого вызова), поэтому я не думаю, что накладные расходы, связанные с многопроцессорной обработкой, могут значительно замедлить его. Любая помощь будет высоко ценится!

+1

Начальные потоки (а также процессы) потребляют _lot_ времени. Возможно, это не ваш код, а медленный процесс, но нерест процессов. – ForceBru

+1

Какой размер 'SectionList', как кажется, ваш' Args' будет иметь размер кортежей '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'означает, что вы начнете размер' Args' на 16 подпроцессов, которые потенциально могут быть много? также, что значит «требуется время, чтобы запустить», может оказаться полезным приблизительная цифра? Далее в списке есть вопрос, каково ваше узкое место? Вы не попадаете в жесткий диск жесткого диска? – user3012759

+0

@ user3012759 - Занимает время, чтобы запустить ', составляет порядка 0,1 с для проблемы, с которой я работаю в данный момент. По крайней мере, это моя оценка - я рассчитал все это без многопроцессорности и 16 разделов (вещь, анализируемая AnalyseSection (Args), а 16 - совпадение - не имеет никакого отношения к количеству процессоров) занимает от 1 до 2 секунд без многопроцессорности и 7 и 8 секунд. На диске нет записи, но, как я уже сказал, я могу получить доступ к справедливому биту ОЗУ. Могут ли ctypes читать библиотеки с диска каждый раз? В любом случае, они всего около 20 КБ, но по сети. –

ответ

1

Это

for i in range(10): 
    for j in range(10): 
     for k in range(10): 
      Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList] 
      pool=mp.Pool(processes=NoCPUs,maxtasksperchild=1) 
      result = pool.map(AnalyseSection,Args) 
      pool.close() 
      pool.join() 

могут и должны быть преобразованы в этот

pool=mp.Pool(processes=NoCPUs) 

for i in range(10): 
    for j in range(10): 
     for k in range(10): 
      Args=[(Sections[i],SectionList[i],ElLoads,ElLoadsM,Materials,CycleCount,FlapF,EdgeF,Scaling,Time,FlapFreq,EdgeFreq) for n in SectionList] 
      result = pool.map(AnalyseSection,Args) 

pool.join() 

Это больше в соответствии с тем, что вы пытаетесь достичь. У вас есть многопроцессорный пул, в котором вы подаете данные и ожидаете результатов. Вам не нужно запускать/останавливать пул на каждой итерации.

Имейте в виду, что при запуске обрабатывается (намного больше, чем потоки, если вы используете потоки).

+0

Спасибо, вы опубликовали, что @ user3012759 помог мне разобраться. Это работает, я думал, что я пробовал это в прошлом, и это не сработало, но я, должно быть, ошибся. –