Как мне профилировать проблемы многопоточности?
Это первый раз, когда я пытаюсь профилировать многопоточные программы.
Я подозреваю, что проблема в том, что она чего-то ждет, но я понятия не имею, что, программа никогда не достигает 100% использования CPU, GPU, RAM или I/O.
До недавнего времени я работал только над проектами с однопоточностью, или там, где потоки были очень просты (например: обычно дополнительный поток, просто чтобы убедиться, что пользовательский интерфейс не заблокирован во время работы программы, или когда я сделал игровой движок с отдельный поток для обработки музыкальных файлов.XM и.IT, так что основной поток может делать все, в то время как другой поток в другом ядре может позаботиться о декодировании этих файлов).
Эта программа имеет несколько потоков, и они не выполняют параллельную работу над одними и теми же задачами, каждый поток имеет свое собственное совершенно отдельное назначение (например, один поток предназначен для обработки всех вызовов API, связанных со звуком, в ОС).
Я скачал инструменты производительности Microsoft, есть блог бывшего сотрудника Valve, в котором объясняется, что они работают над этим, но хотя мне даже удалось создать несколько профилей и еще много чего, я не совсем понял, что вижу, это так. для меня это всего лишь несколько симпатичных графиков (кроме графика использования ЦП, который я уже знал по профилированию на основе выборок в однопоточных приложениях), так как я могу узнать, почему программа чего-то ждет? Или как мне найти то, что ждет? Как мне найти, какой поток блокирует другие?
2 ответа
- Мастер производительности в Visual Studio Концентратор производительности и диагностики имеет режим профилирования "Данные о конфликте ресурсов", который позволяет анализировать конфликты параллелизма между потоками, т. Е. Как на общую производительность программы влияют потоки, ожидающие других потоков. Пожалуйста, обратитесь к этому сообщению в блоге для более подробной информации.
- PerfView - это чрезвычайно мощный инструмент профилирования, который позволяет анализировать влияние потоков и задач службы на общую производительность программы. Вот учебное пособие по PerfView.
Я смотрю на это как на чередование двух вещей:
а) измерения общего времени, для которого все, что вам нужно, это какой-то таймер, и
б) нахождение ускорений, что не означает измерения, несмотря на то, что много людей было сказано.
Каждый раз, когда вы находите ускорение, вы рассчитываете результаты и делаете это снова. Это чередование. Чтобы найти ускорения, я и многие другие люди используют случайную паузу. Идея в том, что вы запускаете программу под отладчиком и вручную прерываете ее несколько раз. Каждый раз вы проверяете состояние каждого потока, включая стек вызовов. Это очень грубо, и это очень эффективно.
Причина, по которой это работает, заключается в том, что программа может работать быстрее только в том случае, если она выполняет действие, которое вы можете удалить, и если это экономит определенную долю времени, вы, по крайней мере, с такой вероятностью будете видеть ее при каждой паузе. Это работает, делает ли он ввод-вывод, ожидание чего-либо или вычисления. Он видит вещи, которые профилировщики не раскрывают, потому что они составляют сводки, от которых можно легко скрыть ускорения.