PDA

View Full Version : fast float to integer


Steve Underwood
11-20-2006, 05:35 PM
Eric de Castro Lopo has a very useful page at
http://mega-nerd.com/FPcast/ about fast float to integer conversion in
C. However, I just realised it doesn't tell the whole story, and I'm a
little puzzled.

When I do what that web page says, conversions are fast inlined
operations. That has been working fine for me for years. I've only just
realised, however, that when I put "-std=c99" on the compiler command
line, the inlined operations change to subroutine calls, and the speed
nosedives. Can anyone tell me why?

Steve

Erik de Castro Lopo
11-20-2006, 07:51 PM
Hi Steve,

Steve Underwood wrote:
>
> Eric de Castro Lopo has a very useful page at

Sorry, thats Erik with a 'k'.


> http://mega-nerd.com/FPcast/ about fast float to integer conversion in
> C. However, I just realised it doesn't tell the whole story, and I'm a
> little puzzled.
>
> When I do what that web page says, conversions are fast inlined
> operations. That has been working fine for me for years. I've only just
> realised, however, that when I put "-std=c99" on the compiler command
> line, the inlined operations change to subroutine calls, and the speed
> nosedives. Can anyone tell me why?

Hmm, thats strange. What optimisation level are you using?
I'm pretty sure that -O0 removes inlinnig but inlining should
still be there at -)2 and above.

Another possibility to to try using -std=gnu99 instead of
-std=c99. gnu99 is basically C99 with POSIX extensions.

Please do report your findings.

Cheers
Erik (with a k, like the Viking)
--
+-----------------------------------------------------------+
Erik de Castro Lopo
+-----------------------------------------------------------+
Diana West for President of the United States
http://www.washtimes.com/op-ed/20060817-091447-7758r.htm
http://www.washtimes.com/op-ed/20060824-084015-5082r.htm

Randy Yates
11-20-2006, 08:32 PM
Erik de Castro Lopo <[email protected]> writes:

> Hi Steve,
>
> Steve Underwood wrote:
>>
>> Eric de Castro Lopo has a very useful page at
>
> Sorry, thats Erik with a 'k'.
>
>
>> http://mega-nerd.com/FPcast/ about fast float to integer conversion in
>> C. However, I just realised it doesn't tell the whole story, and I'm a
>> little puzzled.
>>
>> When I do what that web page says, conversions are fast inlined
>> operations. That has been working fine for me for years. I've only just
>> realised, however, that when I put "-std=c99" on the compiler command
>> line, the inlined operations change to subroutine calls, and the speed
>> nosedives. Can anyone tell me why?
>
> Hmm, thats strange. What optimisation level are you using?
> I'm pretty sure that -O0 removes inlinnig but inlining should
> still be there at -)2 and above.
>
> Another possibility to to try using -std=gnu99 instead of
> -std=c99. gnu99 is basically C99 with POSIX extensions.
>
> Please do report your findings.

I'm curious how you know that enabling optimizations on a compiler
with the lrint() function guarantees the functions will be
inlined. Was it just by experimentation?

In any case, a nice piece of work, Erik. Thanks for making this
knowledge available.
--
% Randy Yates % "Remember the good old 1980's, when
%% Fuquay-Varina, NC % things were so uncomplicated?"
%%% 919-577-9882 % 'Ticket To The Moon'
%%%% <[email protected]> % *Time*, Electric Light Orchestra
http://home.earthlink.net/~yatescr

Steve Underwood
11-21-2006, 12:44 AM
Erik de Castro Lopo wrote:
> Hi Steve,
>
> Steve Underwood wrote:
>
>>Eric de Castro Lopo has a very useful page at
>
>
> Sorry, thats Erik with a 'k'.
>
>
>
>>http://mega-nerd.com/FPcast/ about fast float to integer conversion in
>>C. However, I just realised it doesn't tell the whole story, and I'm a
>>little puzzled.
>>
>>When I do what that web page says, conversions are fast inlined
>>operations. That has been working fine for me for years. I've only just
>>realised, however, that when I put "-std=c99" on the compiler command
>>line, the inlined operations change to subroutine calls, and the speed
>>nosedives. Can anyone tell me why?
>
>
> Hmm, thats strange. What optimisation level are you using?
> I'm pretty sure that -O0 removes inlinnig but inlining should
> still be there at -)2 and above.
>
> Another possibility to to try using -std=gnu99 instead of
> -std=c99. gnu99 is basically C99 with POSIX extensions.
>
> Please do report your findings.

I am using Fedora Core 4, which uses GCC 4.0.2. I tried various things,
once I found the problem.

The following:

#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1

#include <inttypes.h>
#include <tgmath.h>
#include <math.h>

void f2i_array (float *fptr, int *buffer, int count)
{
while (count)
{
count--;
buffer [count] = lrintf (fptr [count]);
}
}

int main(int argc, char *argv[])
{
return 0;
}

compiled with
gcc -o2 -S -o test.S test.c
or
gcc -std=gnu99 -o2 -S -o test.S test.c
the conversions are inlined. Compiled with
gcc -std=c99 -o2 -S -o test.S test.c
they are not, and the code looks considerable different.

Regards,
Steve

Erik de Castro Lopo
11-21-2006, 09:12 AM
Steve Underwood wrote:
>
> I am using Fedora Core 4, which uses GCC 4.0.2. I tried various things,
> once I found the problem.


Thanks Steve. If using -std=c99 or -std=gnu99 then I suspect that
these lines are not needed:

> #define _ISOC9X_SOURCE 1
> #define _ISOC99_SOURCE 1


> compiled with
> gcc -o2 -S -o test.S test.c
> or
> gcc -std=gnu99 -o2 -S -o test.S test.c
> the conversions are inlined. Compiled with
> gcc -std=c99 -o2 -S -o test.S test.c
> they are not, and the code looks considerable different.

I also suspect that once using -O2 the -S (smallest binary)
won't affect the issue either way.

Cheers,
Erik
--
+-----------------------------------------------------------+
Erik de Castro Lopo
+-----------------------------------------------------------+
http://en.wikipedia.org/wiki/Why_I_Am_Not_a_Christian
http://en.wikipedia.org/wiki/Why_I_Am_Not_a_Muslim
http://en.wikipedia.org/wiki/Strong_atheism

Erik de Castro Lopo
11-21-2006, 09:17 AM
Randy Yates wrote:
>
> I'm curious how you know that enabling optimizations on a compiler
> with the lrint() function guarantees the functions will be
> inlined.

I read it somewhere. Sotty, I'm not sure where.

This inlining actually applies to many of the maths functions.

Erik
--
+-----------------------------------------------------------+
Erik de Castro Lopo
+-----------------------------------------------------------+
Turks embrace novelist's war on EU
http://www.iht.com/articles/2005/10/12/news/novel.php

Marc Brooker
11-21-2006, 09:26 AM
Steve Underwood wrote:
>
> When I do what that web page says, conversions are fast inlined
> operations. That has been working fine for me for years. I've only just
> realised, however, that when I put "-std=c99" on the compiler command
> line, the inlined operations change to subroutine calls, and the speed
> nosedives. Can anyone tell me why?
>
> Steve

C99, as far as I remember, places stricter limits on the way the
compiler is allowed to do floating point conversions. I don't have a
copy of the standard nearby, but I remember some changes in that direction.

Have you tried asking this question on one of the gcc mailing lists? The
developers are (like comp.dsp) friendly enough if you obey the basic
rules of netiquette. It is very possible that a change in the standard
made the inline conversions obselete and nobody has written new ones yet.

Steve Underwood
11-21-2006, 03:40 PM
Erik de Castro Lopo wrote:
> Steve Underwood wrote:
>
>>I am using Fedora Core 4, which uses GCC 4.0.2. I tried various things,
>>once I found the problem.
>
>
>
> Thanks Steve. If using -std=c99 or -std=gnu99 then I suspect that
> these lines are not needed:

They aren't needed. I put those in during some experimenting. I found
the information about what gets inlined in GCC 4.0.2 now. That says
lrintf will be inlined unless strict C89 is selected. That doesn't seem
to be the case. -std=c99 stops it being inlined.
>
>
>>#define _ISOC9X_SOURCE 1
>>#define _ISOC99_SOURCE 1
>
>
>
>>compiled with
>> gcc -o2 -S -o test.S test.c
>>or
>> gcc -std=gnu99 -O2 -S -o test.S test.c
>>the conversions are inlined. Compiled with
>> gcc -std=c99 -O2 -S -o test.S test.c
>>they are not, and the code looks considerable different.
>
>
> I also suspect that once using -O2 the -S (smallest binary)
> won't affect the issue either way.

-S means "output assembly language source code, and stop", not make the
smallest binary.

Steve

Carlos Moreno
11-21-2006, 11:52 PM
Steve Underwood wrote:

>> I also suspect that once using -O2 the -S (smallest binary) won't
>> affect the issue either way.
>
> -S means "output assembly language source code, and stop", not make the
> smallest binary.

He probably meant -s, which means "Remove all symbol table and
relocation information from the executable" (if memory serves,
this cut down the size of the executable to about a third of the
size for one particular application I had --- not sure what would
be the typical fraction for arbitrary executables).

Also if memory serves, this option is referred to as "strip binary"
(which is why I think that's what Erik meant in his previous post)

Carlos
--

Erik de Castro Lopo
11-22-2006, 08:38 AM
Carlos Moreno wrote:
>
> He probably meant -s, which means "Remove all symbol table and

You're assuming he (ie me) wasn't babbling :-).

> Also if memory serves, this option is referred to as "strip binary"
> (which is why I think that's what Erik meant in his previous post)

At this time I think we need to agree that gcc has way too many
options for a normal person to remember.

Erik
--
+-----------------------------------------------------------+
Erik de Castro Lopo
+-----------------------------------------------------------+
I call C++ a curse on programmers everywhere; the language
that has enabled and encouraged more stupidity and bad software
design than any other programming language ever.