[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [MiNT] MiNTlib timing related functions behavior/performance
On 04/17/13 15:59, Eero Tamminen wrote:
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).
mktime() is a very bad performer - known fact. One of the packages
I was building decided mktime() was too slow and deemed it unusable
because it took longer than 60 seconds (when compiled with m68000,
m68020-60 is quicker, but still slow.)
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.
Feel free to optimize ! It would be good to have much better performing
functions on the mintlib.
Alan.