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

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

Решение

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

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

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

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

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

Используя методы, которые я описал выше, я перешел с 28% использования ЦП для каждого процесса на 100% использования ЦП. "Застрявшее" состояние больше не появляется.

Другие вопросы по тегам