На Win32, как вы перемещаете поток на другое ядро ​​процессора? - PullRequest
7 голосов
/ 02 октября 2008

Я бы хотел убедиться, что поток перемещен в определенное ядро ​​ЦП и никогда не может быть перемещен из него планировщиком.

Есть SetThreadAffinityMask() звонок, но нет GetThreadAffinityMask().

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

Ответы [ 4 ]

10 голосов
/ 02 октября 2008

Вы, вероятно, должны просто использовать SetThreadAffinityMask и верить, что он работает.

* MSDN 1004 *

4 голосов
/ 03 октября 2008

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

Похоже, вы пытаетесь обойти RDTSC проблемы с перекосом часов. Если вы используете инструкцию RDTSC напрямую, рассмотрите возможность вызова QueryPerformanceCounter() вместо этого:

  • QueryPerformanceCounter() в Windows Vista использует HPET , если он поддерживается чипсетом и находится в таблицах ACPI системы.
  • Системы на базе AMD, использующие Драйвер процессора AMD , в основном компенсируют перекос тактовой частоты многоядерных процессоров, если вы вызываете QueryPerformanceCounter(), но это ничего не делает для приложений, использующих RDTSC напрямую. Двухъядерный оптимизатор AMD - это хак для приложений, которые используют RDTSC напрямую, но если величина перекоса тактовых импульсов изменяется из-за линейного изменения тактовой частоты C1 (где тактовая частота уменьшается в состоянии питания C1 ), вы все равно будете иметь перекос часов. И эти утилиты, вероятно, не очень широко распространены, поэтому использование сходства с QueryPerformanceCounter() все еще является хорошей идеей.
3 голосов
/ 03 октября 2008

Что сказал Кен. Но если вы не доверяете его работе, вы можете снова вызвать SetThreadAffinityMask и подтвердить, что возвращаемое значение соответствует ожидаемой маске. (Но, конечно, если вы не доверяете функции, то вы не можете доверять второму вызову ...)

Не смущайтесь существованием GetProcessAffinityMask. Эта функция не предназначена для проверки работоспособности SetProcessAffinityMask, но, например, так что вы можете создать сходство потоков, которое является подмножеством сходства процессов.

Просто посмотрите на возвращаемое значение и убедитесь, что оно не равно 0, и с вами все будет в порядке.

1 голос
/ 03 октября 2008

Нет необходимости получать Тема AffinityMask. Просто получите значение Get Process AffinityMask, отключите некоторые биты и вызовите SetThreadAffinityMask. Потоки наследуют маску аффинности процесса, и поскольку их аффинность находится под вашим контролем, вы уже знаете маску аффинности нити (это та, которую вы установили).

...