Я изучал проблему в моем приложении DirectX 11 C ++ уже более недели, и поэтому обращаюсь к хорошим людям в StackOverflow за любыми сведениями, которые могут помочь мне отследить эту проблему.
Мое приложение будет работать в основном со скоростью 60-90 кадров в секунду, но каждые несколько секунд я получаю кадр, который занимает около трети секунды, чтобы закончить. После долгих исследований, отладки и использования различных профилировщиков кода я сузил его до обращения к DirectX API. Однако от одного медленного кадра к другому, это не всегда тот же самый вызов API, который вызывает замедление. В моем последнем запуске звонки, которые останавливаются (всегда приблизительно на одну пятую секунды)
Мало того, что это не та же самая функция, которая останавливает, но каждая из этих функций (в основном первые две) медленный вызов может быть из разных мест в моем коде от одного к другому.
В соответствии с несколькими инструментами профилирования и моими собственными таймерами высокого разрешения, которые я поместил в свой код, чтобы помочь измерять вещи, я обнаружил, что этот «сбой» будет происходить с постоянными интервалами чуть менее 3 секунд (~ 2,95).
Это приложение собирает данные с внешнего оборудования и использует DirectX для визуализации этих данных в режиме реального времени. Во время работы приложения аппаратное обеспечение может работать вхолостую или работать на разных скоростях. Чем быстрее оборудование работает, тем больше данных собирается и должно быть визуализировано. Я подчеркиваю это, потому что это может быть полезно при рассмотрении некоторых характеристик этой ошибки:
Эта ошибка постоянно возникает на двух разных машинах с очень похожим оборудованием (две карты GTX580). Однако в последних версиях приложения эта проблема не возникала. К сожалению, код претерпел много изменений с тех пор, поэтому было бы трудно точно определить, какие именно изменения вызывают проблему.
Я рассмотрел графический драйвер и обновил его до последней версии, но это не имело значения. Я также рассмотрел возможность внесения каких-то других изменений в оба компьютера или, возможно, обновление программного обеспечения, работающего на обоих из них, могло вызвать проблемы с графическим процессором. Но я не могу думать ни о чем, кроме Microsoft Security Essentials, который работает на обеих машинах во время работы приложения, и я уже пытался отключить его функцию защиты в реальном времени, но безрезультатно.
Хотелось бы, чтобы причиной была внешняя программа, которую я могу просто отключить, но в конечном итоге я беспокоюсь о том, что я должен что-то делать неправильно / неправильно с API DirectX, из-за которого графическому процессору приходится вносить изменения каждые несколько секунд. Может быть, я что-то не так делаю в способе обновления данных на графическом процессоре (поскольку задержка происходит только тогда, когда я собираю данные для отображения). Затем графический процессор останавливается каждые несколько секунд, и какая функция API, вызываемая во время остановки, не может возвращаться так быстро, как обычно?
Любые предложения будут ценны!
Спасибо,
Тим
ОБНОВЛЕНИЕ (2013.01.21):
Я, наконец, сдался и продолжил поиск по предыдущим версиям моего приложения, пока не нашел точку, где эта ошибка не возникала. Затем я переходил от редакции к редакции, пока не обнаружил, когда именно началась ошибка, и не смог точно определить источник моей проблемы. Проблема начала возникать после того, как я добавил поле «целое число без знака» к типу вершины, для которого я выделил большой буфер вершин. Из-за размера буфера вершин это изменение увеличило размер на 184,65 МБ (с 1107,87 МБ до 1292,52). Поскольку мне действительно нужно это дополнительное поле в моей структуре вершин, я нашел другие способы сократить общий размер буфера вершин и уменьшил его до 704,26 МБ.
Мое лучшее предположение состоит в том, что добавление этого поля и дополнительной памяти потребовало от меня превышения некоторого порога / предела для графического процессора. Я не уверен, было ли это превышением общего объема памяти или превышением некоторого ограничения для одного вершинного буфера. В любом случае, кажется, что это превышение заставило GPU выполнять какую-то дополнительную работу каждые несколько секунд (возможно, связываясь с процессором) каждые несколько секунд, и поэтому мои вызовы API должны были ждать этого. Если у кого-нибудь есть какая-либо информация, которая прояснит значение больших буферов вершин, я бы с удовольствием ее услышал!
Спасибо всем, кто дал мне свое время и предложения.
1) Попробуйте повернуть VSYNC
2) Вы выделяете / освобождаете большие куски памяти? Попробуйте выделить память в начале программы и не освобождать ее, просто перезаписать ее (что, вероятно, вы делаете с updateubresource)
3) Поместите взаимодействие с аппаратным устройством в отдельный поток. После того, как устройство полностью завершит передачу данных в ваше приложение, загрузите его в графический процессор. Не позволяйте устройству контролировать основной поток. Я подозреваю, что устройство часто блокирует основной поток, и Я полностью размышляю но если вы копируете данные с устройства на графический процессор напрямую, устройство время от времени блокируется, что приводит к замедлению работы.
Других решений пока нет …