xash3d-fwgs icon indicating copy to clipboard operation
xash3d-fwgs copied to clipboard

engine: common: disable sleeptime by default for non-mobile platforms

Open SNMetamorph opened this issue 4 years ago • 12 comments

Because it's causes issues with FPS on desktop systems and users had to manually set sleeptime 0 to get rid of this issue.

SNMetamorph avatar Jun 02 '21 16:06 SNMetamorph

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

Я не уверен как можно разрешить эту проблему, не переименовывая квар. Возможно у @mittorn есть какие-то идеи.

a1batross avatar Jul 11 '21 22:07 a1batross

Есть код таймера который я так и не закоммиттил

mittorn avatar Jul 12 '21 00:07 mittorn

Как насчёт отдельного platform конфига?

lewa-j avatar Jul 12 '21 05:07 lewa-j

@lewa-j кстати было бы неплохо. Писать в platform_$(Q_buildos).cfg всё что имеет флаг CVAR_PLATFORM.

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

Не хочется правда заводить новых флагов для кваров. Их бы вообще привести в формат голдсорса, но этим как-нибудь позже можно заняться, вне этого PR.

a1batross avatar Jul 12 '21 06:07 a1batross

Есть код таймера который я так и не закоммиттил

Если я правильно понимаю, нужны как минимум 4 разные реализации такого пробуждающего таймера:

  1. для Windows через win32 api.
  2. для дефолтных posix-совместимых ОС через pthreads.
  3. для linux через eventfd.
  4. для bsd/apple через kqueue(правда в последних версиях FreeBSD и NetBSD присутствует реализация eventfd).

nekonomicon avatar Jun 23 '22 06:06 nekonomicon

Для реализации в Windows можно использовать waitable times, у них разрешение 0.1 мс, чего будет достаточно. Вообще у меня есть этот сниппет с таймерами, когда нибудь я PR сделаю. Насколько помню, я там на чем то застрял. А вот код, о котором говорил @mittorn https://pastebin.com/68uxZdgr https://pastebin.com/HSSX5i9G

SNMetamorph avatar Jun 23 '22 10:06 SNMetamorph

Как я понимаю, после нормальной реализации таймеров можно будет полностью отказаться от квара sleeptime?

SNMetamorph avatar Jun 23 '22 10:06 SNMetamorph

https://pastebin.com/HSSX5i9G

Код из engine/platform/linux/sys_linux.c нужно перенести в engine/platform/posix так как ничего специфичного для линукс там нет.

nekonomicon avatar Jun 23 '22 10:06 nekonomicon

Как я понимаю, после нормальной реализации таймеров можно будет полностью отказаться от квара sleeptime

Думаю да, но я полагаю, что сигнальная система на pthreads может быть не самой эффективной на отдельных ОС так как pthreads везде реализованы по разному и в том же gnu/linux создание потоков и сигнальная система на pthreads медленные, поэтому если это возможно, стоит реализовать будильник на eventfd/kqueue для linux/bsd соответственно.

nekonomicon avatar Jun 23 '22 10:06 nekonomicon

Не стал бы pthreads так использовать.

Лучше busy-wait loop без задержки.

a1batross avatar Jun 23 '22 19:06 a1batross

На атомиках или спинлоках? Ну на винде и так можно лочить/разлочивать все на одном InterlockedExchange без всяких сигналов. То есть в основном потоке пишем в атомик 1, пока предыдущее значение не 0 крутим пустой цикл, а в будильнике после сна пишем в атомик 0.

nekonomicon avatar Jun 23 '22 23:06 nekonomicon

Для реализации в Windows можно использовать waitable times

SetWaitableTimer юзает внутри себя ядерный вызов NtSetTimer, а тот внутри ntoskrnl.exe крутит спинлоки. То есть без лишней шелухи должно быть хорошее решение.

nekonomicon avatar Jun 24 '22 01:06 nekonomicon

Cейчас поэкспериментировал, у waitable timers точность оказалась весьма плохая. Хотя, возможно что дело в каких то флагах.

SNMetamorph avatar Sep 08 '22 11:09 SNMetamorph

Решил проблему с точностью таймеров, вот такой вот интересный сниппет получился:

void SetTimerHighResolution()
{
#if 0
	// undocumented NT API features
	HMODULE hndl = GetModuleHandle("ntdll.dll");
	pNtSetTimerResolution = (pfnNtSetTimerResolution)GetProcAddress(hndl, "NtSetTimerResolution");
	pNtQueryTimerResolution = (pfnNtQueryTimerResolution)GetProcAddress(hndl, "NtQueryTimerResolution");

	ULONG min, max, cur;
	pNtQueryTimerResolution(&min, &max, &cur);
	pNtSetTimerResolution(max, 1, &cur);
#else
	TIMECAPS tc;
	timeGetDevCaps(&tc, sizeof(TIMECAPS));
	timeBeginPeriod(tc.wPeriodMin);
#endif
}

SNMetamorph avatar Sep 08 '22 14:09 SNMetamorph