4

Я работаю в научном учреждении, и одна из задач, над которыми я сейчас работаю, включает в себя запуск симуляции и вывод данных, которые он генерирует, на лету на жесткий диск. Когда я говорю «на лету», я имею в виду, что программа сама выкладывает данные на диск каждую секунду или около того. Эти симуляции написаны исключительно в однопоточном C++ и выполняются на Mac Pro. Соответствующие спецификации этого Mac приведены ниже:

OSX Version: 10.6.8
Model Name: Mac Pro
Model Identifier: MacPro4,1
Processor Name: Quad-Core Intel Xeon
Processor Speed: 2.66 GHz
Number Of Processors: 2
Total Number Of Cores: 8

Intel Xeon с поддержкой многопоточности поддерживает до 8 виртуальных ядер

Я выполняю симуляции в простом файле .sh, используя следующий синтаксис:

nohup simulation1.o configfile 2> /dev/null > /dev/null &
nohup simulation2.o configfile 2> /dev/null > /dev/null &

и так далее...

Использование nohup означает, что мне не нужно беспокоиться о случайных отключениях при удаленной работе.

Когда я смотрю на ps после запуска, скажем, 10, моделирования с использованием моего bash-файла, я обнаруживаю, что в столбце STATE процессы регулярно переключаются с «работы» на «зависание». Кроме того, я ожидаю, что загрузка ЦП будет 100% для каждого процесса, но вместо этого каждый процесс в среднем составляет около 28%. (Я ожидаю, что загрузка ЦП будет 100% для каждого процесса, заключается в том, что когда я запускаю только одну из этих симуляций, столбец ЦП достигает максимума около 100%, добавляя к тому факту, что ядра имеют гиперпоточность. Это очень тяжелая симуляция процессора.)

Кто-нибудь знает, что происходит? В частности:

  • Что означает «застрял» по отношению к ps
  • Почему ЦП не максимально для каждого процесса?

Я был бы очень признателен за помощь.

1 ответ1

1

Я исправил свою проблему. Оказалось, довольно тонко, но благодаря Озаиру - он ударил ногтем по голове. Моя конкретная симуляция не читает очень много данных (только параметры инициализации), но тратит много времени, выплевывая вычисленные данные. Грубый способ, который я реализовал изначально, с использованием стандартного c++ file.open("tobewritten.dat") , очень медленный, даже сам по себе, но когда запускается несколько экземпляров, отдельные экземпляры тратят целую вечность, ожидая «времени записи» на жесткий диск.

Есть несколько конкретных уроков, которые я выучил:

  1. cout << std::endl очищает буфер при использовании; если буфер не заполнен, то более быстрая операция записи в ОЗУ используется неоптимально. Используйте "\n" а затем закройте файл в конце. C ++ обрабатывает сброс буфера на диск, когда он заполнен.

  2. При одновременной записи нескольких массивных файлов данных (я имею в виду ГБ) лучше всего указывать буфер вручную. На данный момент я установил буфер в 50 МБ. Использование больших буферов означает, что ваша система проводит больше времени между оперативной памятью и процессором и выполняет только дамп на диск (медленный бит) с интервалом 50 МБ.

  3. Даже не используйте cout для записи в файл. Это медленнее, чем sprintf и его варианты.

Используя методы, которые я описал выше, я перешел с 28% использования ЦП для каждого процесса на 100% использования ЦП. «Застрявшее» СОСТОЯНИЕ больше не появляется.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .