Что происходит, когда вызывается QueryPerformanceCounter? - PullRequest
19 голосов
/ 12 ноября 2009

Я изучаю точные последствия использования QueryPerformanceCounter в нашей системе и пытаюсь понять его влияние на приложение. Я могу видеть, запустив его на моем 4-ядерном компьютере с одним процессором, что для его запуска требуется около 230 нс. Когда я запускаю его на 24-ядерном 4-процессорном процессоре Xeon, его запуск занимает около 1,4 мс. Более интересно то, что на моей машине, когда она работает в нескольких потоках, они не влияют друг на друга. Но на компьютере с несколькими процессорами потоки вызывают какое-то взаимодействие, которое заставляет их блокировать друг друга. Мне интересно, есть ли какой-нибудь общий ресурс на шине, который они все запрашивают? Что именно происходит, когда я вызываю QueryPerformanceCounter и что он действительно измеряет?

Ответы [ 4 ]

10 голосов
/ 12 ноября 2009

Windows QueryPerformanceCounter () имеет логику для определения количества процессоров и при необходимости запускает логику синхронизации. Он пытается использовать регистр TSC, но для многопроцессорных систем этот регистр не гарантированно синхронизируется между процессорами (и, что более важно, может сильно различаться из-за интеллектуального разгона и состояния сна).

MSDN говорит, что не имеет значения, к какому процессору это вызывается, поэтому вы можете увидеть дополнительный код синхронизации для такой ситуации, что может привести к перегрузкам. Также помните, что он может вызывать передачу по шине, так что вы можете увидеть задержки из-за шины.

Попробуйте использовать SetThreadAffinityMask (), если возможно, чтобы привязать его к определенному процессору. В противном случае вам, возможно, придется смириться с задержкой, или вы можете попробовать другой таймер (например, посмотрите на http://en.wikipedia.org/wiki/High_Precision_Event_Timer).

4 голосов
/ 04 сентября 2010

Я знаю, что эта тема немного старая, но я хотел бы добавить больше информации. Во-первых, я согласен, что QueryPerformanceCounter может занять больше времени на определенных машинах, но я не уверен, что ответ Рона является причиной этого все время. Пока я проводил некоторые исследования по этой проблеме, я нашел несколько веб-страниц, рассказывающих о том, как реализован QueryPerformanceCounter. Например, Точность не совпадает с точностью говорит мне, что Windows, HAL, чтобы быть более конкретным, будет использовать другое устройство синхронизации для получения значения. Это означает, что если в окнах используется более медленное устройство синхронизации, такое как PIT, потребуется больше времени для получения значения времени. Очевидно, что для использования PIT может потребоваться транзакция PCI, что может быть одной из причин.

Я также нашел другую статью: Как это работает: выходы таймера в SQL Server 2008 R2 - инвариантный TSC, дающий аналогичное описание. Фактически, эта статья рассказывает, как SQLServer наилучшим образом рассчитывал время транзакции.

Затем я нашел больше информации на сайте VMware, потому что мне пришлось иметь дело с клиентами, которые используют виртуальные машины, и я обнаружил, что существуют другие проблемы с измерением времени с виртуальными машинами. Для тех, кто заинтересован, обратитесь к статье VMware - хронометраж в виртуальных машинах VMware. В этой статье также говорится о том, как некоторые версии окон будут синхронизировать каждый TSC. Таким образом, было бы безопасно использовать QueryPerformanceCounter () в определенных ситуациях, и я думаю, что мы должны попробовать что-то вроде того, как это работает: выходы таймера в SQL Server 2008 R2 предложили найти, что может произойти, когда мы вызываем QueryPerformanceCounter ()

3 голосов
/ 12 ноября 2009

У меня сложилось впечатление, что на x86 QueryPerformanceCounter () просто вызывал rdtsc под крышками. Я удивлен тем, что на многоядерных машинах наблюдается замедление (я никогда не замечал этого на 4-ядерном процессоре).

2 голосов
/ 12 ноября 2009

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

Вот небольшая статья из MSDN: http://msdn.microsoft.com/ja-jp/library/cc399059.aspx

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

Однако, как я уже говорил, прошло довольно много времени.

Mike

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...