Здравствуйте!
Хотется подельтся некоторыми соображениями о эмуляторе.
В ini файле есть такая строка:Если флаг установлен, то эмуль отдаёт время CPU вызывая Sleep(SLEEP_DELAY). По умолчанию SLEEP_DELAY = 2.; give idle timeslices to other applications
ShareCPU=1 ; 1 - only for fast CPUs (incompatible with SoundDrv=none)
На самом деле, в ОС NT задержка получается совершенно другая. Её время определяется ключём
HKLM\SYSTEM\CurrentControlSet\Control\PriorityCont rol\Win32PrioritySeparation
и составляет (на не серверных версиях) ~15мс.
Измерить время можно, поместив в файл emul.cpp (после стандартных хидеров) код:На практике числа могут быть иные (см. далее)Код:#define SLEEP_TIMING #ifdef SLEEP_TIMING unsigned _tsc; #define Sleep(X) _tsc = rdtsc(), Sleep(X), \ printf("Sleep(%u) time = %u microseconds\r\n", \ X,((rdtsc()-_tsc)/(conf.cpufq/1000000?conf.cpufq/1000000:1))) #endif
Так как длительность кадра Спектрума составляет =20мс, то мулятору при [VIDEO]VSync=1 нужно уложиться в оставшиеся 5мс для вывода кадра. Иначе возможны тормоза. Причём виновата в этом ОС
Документированных способов влиять на планировщик мне не известно, но есть полудокументированный - вызвать где-нибудь при инициализации timeBeginPeriod(1). При этом точность Sleep станет на порядок выше (реально: аргумент_ф-ции+1мс).
Теоретически, это должно позволить мулятору работать на более слабых машинах, чем сейчас.
timeBeginPeriod(1) можно вызывать из любой программы, поэтому, скорость работы эмуля может сильно различаться в зависимости от конфигурации софта (afaik, winamp и некоторые плагины миранды вызывают эту ф-цию).
У меня проц AXP2000+, но при SoundDrv=none fps падает до 35, поскольку Sleep() вызывается в цикле (2*15мс) - с включеным звуком этих проблем нет. При использовании timeBeginPeriod всё нормально
Думаю, такая фича окажется полезной ещё для кого-то.
ЗЫ: На всякий случай аттачу отдельный тест для измерения Sleep и примитивную прогу, которая делает timeBeginPeriod(1) (пока не закрыт MessgeBox) - проверить можно не перекомпилируя эмуль.