Что может заставить мою программу не использовать все ядра через некоторое время? - PullRequest
8 голосов
/ 02 октября 2011

Я написал программу, которая захватывает и отображает видео с трех видеокарт.Для каждого кадра я создаю поток, который сжимает кадр в Jpeg, а затем помещает его в очередь для записи на диск.У меня также есть другие потоки, которые читают из этих файлов и декодируют их в своих собственных потоках.Обычно это работает нормально, это довольно интенсивная загрузка процессора, использующая около 70-80 процентов всех шести процессорных ядер.Но через некоторое время кодирование внезапно замедляется, и программа не может обработать видео достаточно быстро и начинает сбрасывать кадры.Если я проверяю загрузку процессора, я вижу, что одно ядро ​​(обычно ядро ​​5) больше не работает.

Когда это происходит, не имеет значения, выйду ли я и перезапущу ли мою программу.Процессор 5 будет по-прежнему иметь низкую загрузку, и программа сразу начнет сбрасывать кадры.Удаление всего сохраненного видео также не имеет никакого эффекта.Перезагрузка компьютера - единственное, что помогает.Да, и если я установлю привязку моей программы к использованию всего ядра, кроме полуобезжиренного, оно будет работать, пока то же самое не произойдет с другим ядром.Вот мои настройки:

  • AMD X6 1055T (Cool & Quiet OFF)
  • Материнская плата GA-790FX-UD5
  • 4-гигабайтная оперативная память без соединения 1333Mhz '
  • Карты захвата Blackmagic Decklink DUO (x2)
  • Linux - Ubuntu x64 10.10 с ядром 2.6.32.29

Мое приложение использует:

  • libjpeg-turbo
  • posix threads
  • decklink api
  • Qt
  • Написано на C / C ++
  • Все библиотеки связаны динамически

Мне кажется, это было бы какой-то проблемой с тем, как Linux планирует потоки на ядрах.Или есть какая-то причина, по которой моя программа может испортиться настолько, что это не поможет перезапустить программу?

Спасибо за чтение, любой вход приветствуется.Я застрял:)

Ответы [ 2 ]

4 голосов
/ 02 октября 2011

Прежде всего, убедитесь, что это не ваша программа - возможно, вы сталкиваетесь с запутанной ошибкой параллелизма, даже если это не так уж вероятно с вашей программной архитектурой и тем фактом, что перезапуск ядра помогает. Я обнаружил, что, как правило, хорошим способом является отладка после смерти. Скомпилируйте с символами отладки, убейте программу с -SEGV, когда она ведет себя странно, и проверьте дамп ядра с помощью gdb.

2 голосов
/ 02 октября 2011

Я бы попытался выбрать циклический перебор ядра, когда создается новый поток обработки кадров, и прикрепить его к этому ядру.Ведите статистику о том, сколько времени потребуется для запуска потока.Если это фактически ошибка в планировщике Linux - вашим потокам потребуется примерно одинаковое время для запуска на любом ядре.Если ядро ​​действительно занято чем-то другим - ваши потоки, прикрепленные к этому ядру, получат меньше процессорного времени.

...