Re: [LAU] OT(ish): Strange coding problem (audio related)

From: Philipp Überbacher <hollunder@email-addr-hidden>
Date: Sun Jan 30 2011 - 15:29:13 EET

Excerpts from Peter Nelson's message of 2011-01-29 13:47:07 +0100:
> On Sat, 2011-01-29 at 12:07 +0100, Philipp Überbacher wrote:
> > Excerpts from fons's message of 2011-01-28 16:11:52 +0100:
> > > On Fri, Jan 28, 2011 at 02:02:36PM +0100, Philipp Überbacher wrote:
> > >
> > > > rant_begin
> > > > Why can't log mean the same thing everywhere? Why does it need to be
> > > > base e here and base 10 there? Why is there no consistency?
> > > > And why is there no proper logarithmus dualis function? Because you
> > > > can simply do log(n)/log(2)? We've just seen how well this works.
> > > > How about:
> > > > log() - base 10
> > > > ln() - base e - logarithmus naturalis
> > > > ld() - base 2 - logarithmus dualis
> > > > rant_end
> > >
> > > Libm has log(), log10, and log2().
> >
> > Took me a while to figure out that libm is part of glibc :)
> > Good to know that those functions are available on probably pretty much
> > all linux systems.
> >
> > > > The next obvious question is: Does the inaccuracy reliably result in
> > > > values bigger than 11?
> > >
> > > No.
> > >
> > > If the input is a power of two, and you expect an integer as
> > > a result, just do
> > >
> > > k = (int)(log2(x) + 1e-6)
> >
> > log2() suffers from the same problem? I somewhat dislike the idea of
> > adding a constant.
> >
> > > or
> > >
> > > k = (int)(log(x)/log(2) + 1e-6)
> > >
> > > or
> > >
> > > int m, k;
> > > for (k = 0, m = 1; m < x; k++, m <<= 1);
> > >
> > > which will round up if x is not a power of 2.
> >
> > Neat. I thought about it myself yesterday but my ideas weren't exactly
> > brilliant. One idea was to divide by 2, the other to use a small
> > lookup table for powers of 2. I don't really know about efficiency, but
> > I guess bit shifting is as efficient as it gets?
> > Anyway, it's a neat way to avoid the problem and the rounding properties
> > of mult/div in case of not power of 2 could be useful as well.
>
> Well, now I'm just being pedantic :-), but as a quick test using rdtsc
> (i.e. profiling to be taken with a grain of salt):
>
> 1: log(x)/log(2)
> 2: (1 << k) < x
> 3: m < x & m <<= 1
>
> This is 1000 iterations; cycling through x of 512, 1024, 2048, 4096 (to
> prevent the compiler optimizing log(x)/log(2) to a single call
> throughout the whole test). The fourth line is the sum of the iterator
> in each loop.
>
> ./a.out (unoptimized)
> 1 3132000 cycles
> 2 261468 cycles
> 3 285273 cycles
> 1 50500, 2 50500, 3 50500
>
> ./a.out (-O3)
> 1 2598345 cycles
> 2 170055 cycles
> 3 173673 cycles
> 1 50500, 2 50500, 3 50500
>
> I must admit, I'm surprised that fons way shows slightly slower in my
> test!

Is it really surprising (for the non-optimised variant)? Your variant
uses one less variable and assignment. That this isn't optimised away
completely with -O3 does surprise me too.

> As an aside, here's the result with (-O3 -ffast-math)
>
> ./a.out
> 1 150894 cycles,
> 2 169983 cycles,
> 3 158850 cycles,
> 1 47750, 2 50500, 3 50500
>
> Yeah, faster, but wrong :-)
>
> Peter.

After a brief look at man gcc -ffast-math doesn't seem like a very good
idea to use it in general, so no surprise it's not part of -O3 or
something.

Quite interesting stuff, thanks Peter.

_______________________________________________
Linux-audio-user mailing list
Linux-audio-user@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-user
Received on Sun Jan 30 16:15:05 2011

This archive was generated by hypermail 2.1.8 : Sun Jan 30 2011 - 16:15:05 EET