2016-11-22 4 views
2

У меня есть код fortran, который я использую, чтобы рассчитать некоторые количества, связанные с работой, которую я делаю. Сам код включает несколько вложенных циклов и требует очень небольшого ввода-вывода. Всякий раз, когда код изменяется, я запускаю его из набора нескольких входных файлов (чтобы убедиться, что он работает правильно).Последовательная программа работает медленнее с несколькими экземплярами или параллельно

Чтобы сделать длинный рассказ короче, последнее обновление увеличило время работы программы примерно в четыре раза и запустило каждый входной файл поочередно с одним процессором занимает около 45 минут (долго ждать, просто посмотреть, что-то сломалось). Следовательно, я хотел бы запускать каждый из входных файлов параллельно по 4 cpus в системе. Я пытаюсь реализовать параллелизм с помощью сценария bash.

Интересная вещь, которую я заметил, состоит в том, что, когда на машине работает только один экземпляр программы, требуется около трех с половиной минут, чтобы прокрутить один из входных файлов. Когда четыре экземпляра программы запущены, требуется одиннадцать с половиной минут, чтобы прокрутить один входной файл (при этом мое общее время работы сократилось примерно с 45 минут до 36 минут - улучшение, да, но не совсем то, что у меня было надеялся).

Я попытался реализовать параллелизм, используя gnu parallel, xargs, wait и даже просто запустить четыре экземпляра программы в фоновом режиме из командной строки. Независимо от того, как запускаются экземпляры, я вижу, что это замедляется. Следовательно, я уверен, что это не артефакт скриптов оболочки, а что-то происходит с самой программой.

Я попытался восстановить программу с отключенными символами отладки, а также использовать статические ссылки. Ни у одного из них не было заметного влияния. В настоящее время я создаю программу со следующими параметрами:

$ gfortran -Wall -g -O3 -fbacktrace -ffpe-trap = недействительный, ноль, переполнение, нижний поток, denormal -fbounds-check -finit-real = nan -finit-integer = nan -o [название программы] {источники}

Любая помощь или руководство будут высоко оценены!

+0

Вы уверены, что используете GNU Parallel Shell? Если нет, проверьте описание тегов и используйте только те, которые применяются. Кроме того, действительно ли имеет значение bash? Возможно, потребуется какой-то код. –

+0

Да, я попытался использовать GNU параллельно в качестве решения. Я также пытался использовать xargs, ждать и просто запускать несколько экземпляров в фоновом режиме. –

+0

У вас есть четыре аппаратных ядра? Тяжелая пропускная способность вашей программной памяти? Предоставьте более подробную информацию о вашем оборудовании и примерной программе. – IanH

ответ

1

На современных процессорах вы не можете ожидать линейного ускорения. Есть несколько причин:

  • Hyperthreading GNU/Linux будет видеть гиперпоточность как ядро ​​Eventhough это не реальное ядро. Это больше похоже на 30% ядра.

  • Общие кэши Если ядра одни и те же кэш и один экземпляр вашей программы в полной мере использует общий кэш, то вы получите больше кэш-промахов при запуске нескольких экземпляров.

  • Пропускная способность памяти Аналогичный случай как общий кэш - это пропускная способность общей памяти. Если в одном потоке используется полная пропускная способность памяти, тогда запуск большего количества заданий параллельно может привести к увеличению пропускной способности. Это частично можно решить, запуская NUMA, где каждый процессор имеет некоторую ОЗУ, которая «ближе», чем другая оперативная память.

  • Turbo mode Многие процессоры могут запускать один поток с более высокой тактовой частотой, чем несколько потоков. Это связано с теплом.

Все они будут демонстрировать один и тот же симптом: Запуск один поток будет быстрее, чем каждый из нескольких потоков, но общая пропускная способность нескольких потоков будет больше, чем один поток.

Хотя я должен признать, ваше дело звучит крайность: С 4 ядрами я ожидал бы ускорение, по крайней мере, 2.

Как определить причину

  • Hyperthreading Использование taskset выбрать, какие ядра запускать. Если вы используете 2 из 4 ядер, есть ли разница, если вы используете # 1 + 2 или # 1 + 3?

  • Turbo mode Используйте cpufreq-set, чтобы заставить низкую частоту. Является ли скорость тем же самым, если вы параллельно выполняете 1 или 2 задания?

  • общий кэш Не знаете, как это сделать, но если это как-то можно отключить кэш, а затем сравнивая 1 задание 2 заданий, выполняемых на одной и той же низкой частоты должен давать показания.

+0

-fbounds-check не заставляет код работать быстрее, а некоторые другие -Wall также замедляют работу. Я не знаю, как работает один кеш без использования нескольких продуктов, которые явно предназначены для этого. – Holmz

+0

Использование 'taskset' и принудительное использование четырех экземпляров для двух процессоров приводит к немногому увеличению времени работы часов по сравнению с четырьмя экземплярами на четырех процессорах (12,5 минут по сравнению с 11 минутами). Время CPU значительно короче, когда четыре экземпляра работают на двух процессорах (6,25 минут по сравнению с 10,67 минутами). –

+0

Можете ли вы запустить 2 задания на 2 ядра, но попробуйте ядро ​​# 1 + 2, а затем # 1 + 3. Есть ли разница? –

Смежные вопросы