[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] MiNTlib timing related functions behavior/performance



Hi,

I was profiling Quake (II) and Doom code compiled with Vincent's toolchain
i.e. with new MiNTlib, on (emulated) Falcon and found something you might
be interested...

By far most of the time in Quake startup, and in rendering a frame
in Doom, is spent by localtime.o from MiNTlib, between these symbols
in the binary:
---
d0fd0 T localtime.o
d30fc T _tzsetwall
---
tzsetwall is symbol from localtime, but for some reason there are no
symbols before that in the linked in localtime.o content, although
one can see them with "mn":
---------------------
$ ar x libc.a
$ nm localtime.o | sort -n
...
         U _strncpy
000025e6 T _tzset
000027ae T _mktime
000027c6 T _timelocal
000027dc T _timegm
000027fc T _timeoff
0000274a T _gmtime_r
0000275e T _offtime
0000278a T _ctime_r
0000281e T _time2posix
00002572 T _tzsetwall
...
---------------------

And most of the time in those two programs is spent in addresses
between these symbols, "localtime.o" and "_tzsetwall"...


When I started to look what happens in MiNTlib timing related functions,
I found something I consider a bit horrible...


Quake code uses gettimeofday() and (u)sleep. Because of memory
requirements etc, it's not possible to run it under MiNT.


Sleep does some funny stuff with sigalarm() on MiNT and calls clock()
on TOS.  Usleep() uses Fselect() on MiNT and calls _clock() on TOS.
Usage of clock() is fine performance-wise.

However, gettimeofday():
* uses Tgettimeofday() on MiNT and Tgettime() & Tgetdate() on TOS.
* Then it does mktime() which does timezone stuff, and if non-null
  value is given as timezone arg (like Quake does), it will also
  call timezone stuff directly.

Currently it's assumed that this is the culprit for bad performance,
it will hopefully be soon verified (by removal of this call & re-testing).

>From my very quick reading of MiNTlib localtime.c, it seems that most
of timezone parsing stuff is done always (.e. twice in current Quake
case).  Is this true?


nanosleep() (not used in Quake) is even worse:
- it uses gettimeofday() (with NULL timezone parameter),
- then it does select(), which on TOS returns error I think, and
- as result it will call gettimeofday() again.

nanosleep() can, and is used, for shorter sleeps than sleep(), so 
it taking a lot more CPU than sleep(), especially on TOS, is IMHO
not really acceptable.


Btw. As to games ported e.g. from Linux, from reading upstream libSDL
code, it seems that with MiNTlib it will end up using gettimeofday()
for SDL_GetTicks() and nanosleep() for SDL_Delay().


	- Eero

Ps. Because nanosleep() & gettimeofday() are one of the most often
called OS functions, on Linux they have their own specially optimized
system calls...