5мс - это больше трети кадра. Что такое Thread.SpinLock?
Вид для печати
не совсем, это цикл операций, в которых не задействуются вычислительные блоки процессора, таким образом они могут быть использованы другими потоками. Но при этом наш поток не переключается на чужие задачи.
Потестил на других машинах, оказалось не везде такая красивая картинка, на некоторых машинах довольно сильный разброс. Видимо там где time-slice довольно большой и Thread.Sleep со слишком большими квантами времени работает.
А есть способ уменьшить кванты времени на Win 7? в старых системах помню можно было какой-то апишный вызов сделать и система переходила в рилтайм режим с низким time slice
---------- Post added at 19:12 ---------- Previous post was at 19:10 ----------
я сам давно хочу его реализовать, но для этого нужно разобраться как оно работает :)
1) На сколько я знаю (может я отстал от новых процессоров) каждое ядро имеет свой набор вычислительных блоков.
2) Зачем нужен этот цикл? Какая от него польза, если это просто пустой цикл на заданное число итераций?
---------- Post added at 23:31 ---------- Previous post was at 23:05 ----------
В EmuStidio я делаю так:
Выполнять в realtime-приоритете процесса. В этом приоритете ни один другой процесс не может получить квант времени, пока вы его не отдадите по Sleep. Т.е. если ваш процесс его не отдаст, то система зависнет железно (во всяком случае с одним ядром, проверял на XP). Возможно, что на современных виндах такой приоритет можно получить только под админом, я не проверял. Альтернативный вариант - это приоритет чуть меньше - high priority. Но он не дает гарантий точного измерения.
Как известно, высота экрана в сканлайнах состоит из видимой части (которую нам сообщает система) и невидимой (VBlank части). Невидимая часть на LCD мониторах может быть равна 0 или 1. Для CRT-мониторов невидимая часть может быть несколько десятков сканлайнов.
Алгоритм таков:
1) Определяем видимую высоту экрана в сканлайнах через dwHeight
2) Ждем пока луч не дойдет до середины экрана. Делаем это так:
a) Sleep(1)
b) Считываем номер сканлайна
c) Если номер сканлайна меньше dwHeight/2, то цикл --> a)
Таким образом мы отдаем около 50% быстродействия системе, дабы система не тормознула во время дальнейших измерений, ведь мы в realtime-приоритете.
3) Далее определяем точку перехода через 0-й сканлайн:
a) Считываем номер сканлайна
b) Если номер сканлайна не меньше предыдущего, то цикл --> a)
Таким образом полная высота экрана будет равна максимальному номеру сканлайна плюс 1
Данный процесс я делаю несколько раз подряд, и проверяю, чтобы все 3 последовательных результата (за 3 кадра) были одинаковыми. Если так, то считаю измерение выполненным правильно.
Теперь об установки минимальной дискретности для Sleep (т.е. для переключения процессов). Я это делаю через timeBeginPeriod(1). Во всех системах это прокатывает. Какое получилось реальное разрешение таймера можно потом проверить так:
Код:TIMECAPS tc;
timeGetDevCaps(&tc,sizeof(TIMECAPS));
printf("Timer Period Min - %dms\n", tc.wPeriodMin);
На одном ядре обычно два потока исполняется, при этом они шарят между собой вычислительные блоки. Если нужный блок занят одним потоком, то второй простаивает или пытается выполнить другие инструкции, если это возможно до выполнения текущей. Кроме того ядра тоже шарят между собой какието блоки, например общий кэш. Просто цикл, даже из nop загружает блоки процессора и второй поток из-за этого тормозится. Плюс к этому время холостого цикла процессор может использовать для синхронизации кэша или для своих оптимизаций. Если выполнять тупой цикл, то процессор не получит такой возможности
Это не так, даже с рилтаймом система отобрает процессор для своих более важных задач. Да и зависаний никаких нет от рилтайма. Сегодня возился, пробовал и realtime+highest приоритет (это максимум) - синхра стабильнее, но видно что система отбирает процессор
---------- Post added at 23:00 ---------- Previous post was at 22:58 ----------
Смысл в том что раз уж берем блокируем поток на холостой цикл, то нужно хотябы поделиться блоками процессора с другими потоками и дать прцессору пооптимизировать свои кэши. Это лучше чем тупо жрать вхолостую ресурсы