Re: Fast fmodf(..., 1.0f)
- From: "jason.cipriani@xxxxxxxxx" <jason.cipriani@xxxxxxxxx>
- Date: Mon, 30 Jun 2008 12:23:56 -0700 (PDT)
On Jun 29, 7:47 pm, "jason.cipri...@xxxxxxxxx"
<jason.cipri...@xxxxxxxxx> wrote:
On Jun 29, 4:50 pm, pete <pfil...@xxxxxxxxxxxxxx> wrote:
I would expect modff to be faster at breaking a float
into integer and fractional parts, simply because,
unlikefmodf, it can't be used for anything else.
Thanks! I didn't know about this function. I'll see if it improves the
speed when I get a chance to test. To make it work with negative
numbers like I want it to, it will be (using doubles, although in
reality I'm doing this in C++ and using the C++ std::modf version that
works with floats) something like this:
It seems that modff is significantly slower than fmodf, taking about
1.5 to 2 times longer -- I'm imagining it has something to do with the
fact that it returns both the fractional AND integer parts. The
program I used to time it is at the end of this message. If you run it
provide a non-zero argument, fmodf is significantly slower when you
pass 0.0f to it for some reason.
Compiled with MinGW GCC 3.4.5:
gcc -std=c99 -O0 fmodtest.c
Results, in performance counter ticks (actual units here are
arbitrary, relative values are meaningful), Intel T2600 at 2.16 GHz:
$ ./a.exe -1.5
fmodf = 1514
modff = 2482
$ ./a.exe 0
fmodf = 2176
modff = 2409
$ ./a.exe 1.5
fmodf = 1411
modff = 2411
Differences when the value is in or out of the range [-1,1] are
negligible.
Program follows; if you aren't using Windows you'll have to fill in
something appropriate for timerval_t, tick(), and tickdiff(). You can
use gettimeofday() on Linux.
Jason
======== modtest.c =========
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
/* do what you need to do here */
#ifdef _WIN32
# include <windows.h>
typedef LARGE_INTEGER timerval_t;
# define tick QueryPerformanceCounter
# define tickdiff(a,b) ((b).QuadPart - (a).QuadPart)
#else
/* typedef ... timerval_t;
void tick (timerval_t *t) { ... }
timerval_t tickdiff (timerval_t a, timerval_t b) { ... } */
#endif
#define ITERS 1000
inline float mymoda (float v) {
if (v >= 0.0f)
return fmodf(v, 1.0f);
else
return 1.0f - fmodf(-v, 1.0f);
}
inline float mymodb (float v) {
float ipart;
if (v >= 0.0f)
return modff(v, &ipart);
else
return 1.0f - modff(-v, &ipart);
}
int main (int argc, char **argv) {
timerval_t a1, a2, b1, b2;
float v, s = 0.0f;
unsigned n;
unsigned long at, bt;
/* v is non-constant to prevent optimizations with > -O0 */
v = atof(argv[1]);
printf("using value %f\n", v);
tick(&a1);
for (n = 0; n < ITERS; ++ n) {
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
s += mymoda(v);
}
tick(&a2);
tick(&b1);
for (n = 0; n < ITERS; ++ n) {
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
s += mymodb(v);
}
tick(&b2);
at = (unsigned long)tickdiff(a1, a2);
bt = (unsigned long)tickdiff(b1, b2);
printf("fmodf = %lu\nmodff = %lu\n", at, bt);
/* prevent calculations from being optimized away with > -O0 */
return (int)s;
}
.
- References:
- Fast fmodf(..., 1.0f)
- From: jason.cipriani@xxxxxxxxx
- Re: Fast fmodf(..., 1.0f)
- From: pete
- Re: Fast fmodf(..., 1.0f)
- From: jason.cipriani@xxxxxxxxx
- Fast fmodf(..., 1.0f)
- Prev by Date: Re: Storing input into a character array
- Next by Date: Re: adding colums to text
- Previous by thread: Re: Fast fmodf(..., 1.0f)
- Next by thread: Re: Fast fmodf(..., 1.0f)
- Index(es):
Relevant Pages
|