Приложение DirectX & quot; икота & quot; каждые 3 секунды

Я изучал проблему в моем приложении DirectX 11 C ++ уже более недели, и поэтому обращаюсь к хорошим людям в StackOverflow за любыми сведениями, которые могут помочь мне отследить эту проблему.

Мое приложение будет работать в основном со скоростью 60-90 кадров в секунду, но каждые несколько секунд я получаю кадр, который занимает около трети секунды, чтобы закончить. После долгих исследований, отладки и использования различных профилировщиков кода я сузил его до обращения к DirectX API. Однако от одного медленного кадра к другому, это не всегда тот же самый вызов API, который вызывает замедление. В моем последнем запуске звонки, которые останавливаются (всегда приблизительно на одну пятую секунды)

  • ID3D11DeviceContext: UpdateSubresource
  • ID3D11DeviceContext: DrawIndexed
  • IDXGISwapChain: Присутствует

Мало того, что это не та же самая функция, которая останавливает, но каждая из этих функций (в основном первые две) медленный вызов может быть из разных мест в моем коде от одного к другому.

В соответствии с несколькими инструментами профилирования и моими собственными таймерами высокого разрешения, которые я поместил в свой код, чтобы помочь измерять вещи, я обнаружил, что этот «сбой» будет происходить с постоянными интервалами чуть менее 3 секунд (~ 2,95).

Это приложение собирает данные с внешнего оборудования и использует DirectX для визуализации этих данных в режиме реального времени. Во время работы приложения аппаратное обеспечение может работать вхолостую или работать на разных скоростях. Чем быстрее оборудование работает, тем больше данных собирается и должно быть визуализировано. Я подчеркиваю это, потому что это может быть полезно при рассмотрении некоторых характеристик этой ошибки:

  • Длинные кадры не возникают, когда оборудование не используется. Это имеет смысл для меня, потому что программное обеспечение просто должно перерисовать данные, которые у него уже есть, и не должно передавать новые данные в графический процессор.
  • Однако длинные кадры появляются с этими постоянными интервалами в 3 секунды, независимо от скорости работы оборудования. Поэтому, даже если мое приложение собирает вдвое больше данных в секунду, частота длинных кадров не меняется.
  • Продолжительность этих длинных кадров очень постоянна. Всегда между 0,25 и 0,3 секундами (я полагаю, что это медленный вызов API DirectX, который является последовательным, поэтому любое изменение общей длительности кадра является внешним по отношению к этому вызову).
  • Во время полевого тестирования на прошлой неделе (когда я впервые обнаружил проблему), я заметил, что после нескольких запусков приложения, после длительного (вероятно, 20 минут или более) непрерывного тестирования без особого взаимодействия с программой, кроме ее просмотра, икота уйдет. Икота вернулась бы, если бы мы взаимодействовали с некоторыми функциями приложения или перезапустили программу. Это не имеет смысла для меня, но почти как GPU «разобрался» и исправил проблему, но затем вернулся, когда мы изменили схему работы, которую он выполнял ранее. К сожалению, природа нашего оборудования мешает мне воспроизвести это в лабораторной среде.

Эта ошибка постоянно возникает на двух разных машинах с очень похожим оборудованием (две карты GTX580). Однако в последних версиях приложения эта проблема не возникала. К сожалению, код претерпел много изменений с тех пор, поэтому было бы трудно точно определить, какие именно изменения вызывают проблему.

Я рассмотрел графический драйвер и обновил его до последней версии, но это не имело значения. Я также рассмотрел возможность внесения каких-то других изменений в оба компьютера или, возможно, обновление программного обеспечения, работающего на обоих из них, могло вызвать проблемы с графическим процессором. Но я не могу думать ни о чем, кроме Microsoft Security Essentials, который работает на обеих машинах во время работы приложения, и я уже пытался отключить его функцию защиты в реальном времени, но безрезультатно.

Хотелось бы, чтобы причиной была внешняя программа, которую я могу просто отключить, но в конечном итоге я беспокоюсь о том, что я должен что-то делать неправильно / неправильно с API DirectX, из-за которого графическому процессору приходится вносить изменения каждые несколько секунд. Может быть, я что-то не так делаю в способе обновления данных на графическом процессоре (поскольку задержка происходит только тогда, когда я собираю данные для отображения). Затем графический процессор останавливается каждые несколько секунд, и какая функция API, вызываемая во время остановки, не может возвращаться так быстро, как обычно?

Любые предложения будут ценны!

Спасибо,
Тим

ОБНОВЛЕНИЕ (2013.01.21):

Я, наконец, сдался и продолжил поиск по предыдущим версиям моего приложения, пока не нашел точку, где эта ошибка не возникала. Затем я переходил от редакции к редакции, пока не обнаружил, когда именно началась ошибка, и не смог точно определить источник моей проблемы. Проблема начала возникать после того, как я добавил поле «целое число без знака» к типу вершины, для которого я выделил большой буфер вершин. Из-за размера буфера вершин это изменение увеличило размер на 184,65 МБ (с 1107,87 МБ до 1292,52). Поскольку мне действительно нужно это дополнительное поле в моей структуре вершин, я нашел другие способы сократить общий размер буфера вершин и уменьшил его до 704,26 МБ.

Мое лучшее предположение состоит в том, что добавление этого поля и дополнительной памяти потребовало от меня превышения некоторого порога / предела для графического процессора. Я не уверен, было ли это превышением общего объема памяти или превышением некоторого ограничения для одного вершинного буфера. В любом случае, кажется, что это превышение заставило GPU выполнять какую-то дополнительную работу каждые несколько секунд (возможно, связываясь с процессором) каждые несколько секунд, и поэтому мои вызовы API должны были ждать этого. Если у кого-нибудь есть какая-либо информация, которая прояснит значение больших буферов вершин, я бы с удовольствием ее услышал!

Спасибо всем, кто дал мне свое время и предложения.

9

Решение

1) Попробуйте повернуть VSYNC

2) Вы выделяете / освобождаете большие куски памяти? Попробуйте выделить память в начале программы и не освобождать ее, просто перезаписать ее (что, вероятно, вы делаете с updateubresource)

3) Поместите взаимодействие с аппаратным устройством в отдельный поток. После того, как устройство полностью завершит передачу данных в ваше приложение, загрузите его в графический процессор. Не позволяйте устройству контролировать основной поток. Я подозреваю, что устройство часто блокирует основной поток, и Я полностью размышляю но если вы копируете данные с устройства на графический процессор напрямую, устройство время от времени блокируется, что приводит к замедлению работы.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]