?

Log in

No account? Create an account
nyaload

Журнал Пушыстого

Журнал Пушыстого

Previous Entry Share Next Entry
Преждевременная оптимизация-2
nyaload
_winnie
Думал, такое бывает только в шутках про "секретные базы темных джедаев". Тем не менее, я сегодня нашёл ::Sleep(1) внутри главного цикла игры.
Исходя из окружающего кода и местоположения (получение статистики про FPS), считаю что его там забыли, как хирург обычно забывает скальпель внутри оперируемого.
В среднем ::Sleep(1) выполняется две миллисекунды, и удаление этого левого кода увеличивает FPS с 50 до 55.

updated. Поддержка заявила что Sleep в счетчике FPS - это таки что бы другие потоки могли загружать в фоне ресурсы. Пипец, даже если ничего не грузится, то всё равно поспим на каждом кадре. Впрочем, сказали что на многоядерной системе можно Sleep убрать.

  • 1
А при чем здесь оптимизация-то? Это же пессимизация в чистом виде.

Это как "машлык" прилепляется к шашлыку или воробей - стреляный. Так и оптимизация, если есть оптимизация - то обязательно преждевременная.

Соптимизировал игру за 2 месяца до релиза не поменяв ни строчки в SVN-е.
В два раза вырос FPS.

Этих "заброшенных ракетных баз в Сибири" - слишком много.
Чем длиннее проект, чем чаще меняют программистов - тем больше.


А ты не слишком поторопился? Может подождать, пока FPS упадёт хотя бы до 45, тогда и запускать секретные ракеты? ;)

new_fps = 1.0/(1.0/old_fps - 0.002)

В заварушке "гильдия против гильдии с армиями мобов вокруг" FPS может быть 15, а в тихом лесу - 120.

Таки похоже ты чью-то заначку стырил.

Где вы берете все эти исходники?..

а откуда известно про среднее время в две миллисекунды?
мне казалось, что подобные слипы выполняются в среднем за time slice/2.

В цикле в отдельном exe прогнал, for (int i = 0; i < 1000; ++i) ::Sleep(1);

а какая вынь/железо? чем мерилось общее время?
а 1000 не мало ли?
я попробую 100000 на досуге.

код:

#include <windows.h>
#include <stdio.h>

const int N = 1000;
double samples[N];

int main()
{
	LARGE_INTEGER frequency; 
	QueryPerformanceFrequency( &frequency );
	
	LARGE_INTEGER a, b;

	for (int i = 0; i < 1000; ++i)
	{
		QueryPerformanceCounter( &a );
		::Sleep(1);
		QueryPerformanceCounter( &b );
		
		samples[i] = double(b.QuadPart - a.QuadPart) / frequency.QuadPart;
	}
	
	for (int i = 0; i < 1000; ++i)
		printf("%g\n", samples[i]);
}


Результат: http://www.everfall.com/paste/id.php?ib4uhysgc92s
Почти все значения - вокруг 1.9.


тот же код даёт у меня

0.000933873
0.00104446
0.000958833
0.000999152
0.00109553
т.е. всё около 1мс

win7x64, 2xW3520@2.66Ghz

где бы взять одноядерную машину померить %)

большая просьба прогони тот же цикл только со Sleep(0); - сколько он займет?... хотя тут все зависит от того чем занят комп, сколько ядер и пр.
Вроде как именно Sleep(0); рекомендуют ставить что бы дать время другим процессам-тредам на 1но процессорной машине. (если ничего не путаю).

Ну, он займёт какое-то случайное время в зависимости от загруженности системы.

У меня два ядра. Когда загружены оба ядра данный цикл завис надолго, уже несколько минут работает. Когда занято одно ядро или ни одного - то отработал мгновенно, за 0.04 секунды.

Если что-то загружает процессор но периодически спит - то возможны все промежуточные варианты.

#include <windows.h>

int main()
{
	for (int i = 0; i < 100000; ++i)
	{
		::Sleep(0);
	}
}



это понятно и ожидаемо.
но т.к. ты умудрился (в твоих конкретных условиях) померить Sleep(1) то стало интересно в тех же условиях замеры Sleep(0)

+я ещё грубо замерял FPS с выключенным и включенным куском кода (в рантайме булевский флажок менял). Там получилось значение 1.3

есть подозрения что народ пишущий Sleep(1) не знает про SwitchToThread

  • 1