Процессы в Mac OSX зависают и странное использование процессора

3111
Mani

Я работаю в научном учреждении, и одна из задач, над которыми я сейчас работаю, заключается в запуске симуляции и выводе данных, которые она генерирует, на лету на жесткий диск. Когда я говорю «на лету», я имею в виду, что программа сама выкладывает данные на диск каждую секунду или около того. Эти симуляции написаны исключительно в однопоточном 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
  • Почему ЦП не максимально для каждого процесса?

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

4
Я думаю, что поскольку данные записываются на жесткий диск на лету, наиболее вероятно, что процесс ожидает записи данных большую часть времени и имитирует их меньше. Я думаю, что вы должны иметь отдельный поток для записи на диск Ozair Kafray 11 лет назад 2
@OzairKafray: ОС должна делать записи полностью асинхронными, если достаточно памяти для их буферизации. Поэтому, если код написания не нарушен, многопоточность вряд ли поможет. Скорее всего, он заблокирован на диске * читает *. David Schwartz 11 лет назад 1
@ ДавидШвартаз Я вижу, вы, скорее всего, правы! Ozair Kafray 11 лет назад 0

1 ответ на вопрос

1
Mani

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

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

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

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

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

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

Похожие вопросы