5
« on: August 28, 2007, 08:51:24 pm »
It's not that that isn't possible, it's just that that seems like a waste as whatever method internally used will originally return as an integer.
Ok, having looked at the source of sfClock and sfPlatform::GetSystemTime() I can see that on windows the function QueryPerformanceFrequency is used. I can also that a static cast to a double is used. A cast to a double is slow and unneeded(and any operations on a double will also be slow), even a cast to a float can be considered slow, and making me cast that double or float back to a int is also slow and a waste.
As you may not believe me that a float to int converstion (or the other way around or for a double) is slow, I will post the code microsoft vc++ 2003 will create in a function call called _ftol2. (New versions of the compiler will produce similar code.) The reason for this lengthy code is to keep ANSI compliance with regard to rounding when casting and the fact that PC apps under x86 use a different rounding mode by default.
(inline code)
fld dword ptr [esp+8]
call _ftol2
(then)
_ftol2:
004010D0 push ebp
004010D1 mov ebp,esp
004010D3 sub esp,20h
004010D6 and esp,0FFFFFFF0h
004010D9 fld st(0)
004010DB fst dword ptr [esp+18h]
004010DF fistp qword ptr [esp+10h]
004010E3 fild qword ptr [esp+10h]
004010E7 mov edx,dword ptr [esp+18h]
004010EB mov eax,dword ptr [esp+10h]
004010EF test eax,eax
004010F1 je integer_QnaN_or_zero (40112Fh)
arg_is_not_integer_QnaN:
004010F3 fsubp st(1),st
004010F5 test edx,edx
004010F7 jns positive (401117h)
004010F9 fstp dword ptr [esp]
004010FC mov ecx,dword ptr [esp]
004010FF xor ecx,80000000h
00401105 add ecx,7FFFFFFFh
0040110B adc eax,0
0040110E mov edx,dword ptr [esp+14h]
00401112 adc edx,0
00401115 jmp localexit (401143h)
positive:
00401117 fstp dword ptr [esp]
0040111A mov ecx,dword ptr [esp]
0040111D add ecx,7FFFFFFFh
00401123 sbb eax,0
00401126 mov edx,dword ptr [esp+14h]
0040112A sbb edx,0
0040112D jmp localexit (401143h)
integer_QnaN_or_zero:
0040112F mov edx,dword ptr [esp+14h]
00401133 test edx,7FFFFFFFh
00401139 jne arg_is_not_integer_QnaN (4010F3h)
0040113B fstp dword ptr [esp+18h]
0040113F fstp dword ptr [esp+18h]
localexit:
00401143 leave
00401144 ret
This is expensive considering it will be called twice (well once, but some similar code to convert it back) and is totally unneeded.
So the current method is definitely not optimal and will loose precision for no reason.
Lastly, I am not trying to be awkward, I like this library and I just want it to be the best it can. If you still think its not needed, fair enough, I just think it would be something useful and not very hard to implement.
Oh and just in case you are wondering what an optimised float to int looks like (not ANSI compliant as it truncates or rounds depending on the processor mode) ->
float a = 1.0f;
int b;
__asm
{
fld a
fistp b
}
Microsoft will actually use this if you select the command option '/QIfist', but this is getting off topic as my point was the casts are unnessary and loose precision and we are not even dealing with floats here.