SpinWait - Почему и как это происходит?

Спасибо, что нашли время посмотреть на мой вопрос.

Я работаю над мультимедийным приложением, основанным в основном на.NET 4.7, DXGI, DirectX 12 и RawInput.

Подводя итог, можно сказать, что приложение начинает свою жизнь как NativeWindow без каких-либо добавок. Он инициализирует DirectX и RawInput в соответствии с оборудованием хоста и запускает их в своих собственных потоках.

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

Работая над некоторыми материалами для планшетов Wacom в RawInput, я вставил следующий код с небольшой задержкой:

Threading.SpinWait.SpinUntil(Function()                                  
      Thread.Sleep(New TimeSpan(10000))
                           Return True
                          End Function)

Полусонный, я закончил тем, что добавил его в метод, который вызывается из потока DirectX.

Вот где все стало интересно.

Прежде всего, каждый раз, когда вызывался содержащий метод, загрузка процессора снижалась... но не процессор, выполняющий поток, из которого был вызван метод... (поток DirectX имеет привязку к процессору).

Во-вторых, значения, возвращаемые из моего потока таймера, стали менее "дрожать" - последовательные вызовы QueryPerformanceCounter обычно колебались на степень около 8-20%, но я подумал, что это произошло из-за частоты, с которой он вызывался (получая истекшие значения в низкий диапазон тиков 1000-х).

Parallel.For (6 потоков), выполняющий интеграцию Verlet на нескольких тысячах геометрий, неожиданно способен обрабатывать примерно на 30% больше работы, даже несмотря на то, что с самого начала он никогда не платил должным образом ЦП (плохое разбиение).

Почему вызов этого запаха кода метода влияет на другие потоки и другие ядра процессора? Я проверил источник SpinWait и понял, как работает Yield(), но вызов его самостоятельно, или Sleep(1), как это часто делает SpinWait, не дает того же эффекта.

Процессор Dev - это i7-8750H.

0 ответов

Другие вопросы по тегам