libsbc optimizing
Hi,
I have been looking at the problem of libsbc performance on arm. My first pass is on the decoder. I'm trying to cut down deeply nested fp multiply/divide ops.
I originally planned regression tests in the build process for performance/correctness but decided against them:
- performance may actually go down on x86 where I build when we reduce fp usage
- the character of roundoff errors will change and the lossy stream
will probably look different even when it is still "correct"
Anyway, I will need to know the range of certain values in order to make much progress. I tried hunting down how they are calculated but it gets difficult very quickly.
Can I get help with the ranges for bits[ch][sb] in sbc_unpack_frame and the state.* vectors if they're bounded?
How about this first little patch?
Brad
Index: sbc/sbc.c
===================================================================
RCS file: /cvsroot/bluetooth-alsa/btsco/sbc/sbc.c,v retrieving revision 1.33
sbc.c +5 -6
@@ -391,7 +391,6 @@ static int sbc_unpack_frame(const u_int8int bits[2 ][8 ];/* bits distribution */ int levels[2 ][8 ];/* levels derived from that */ -double scalefactor[2 ][8 ];/* derived from frame->scale_factors */ if (len <4 )return -1 ;
@@ -525,7 +524,6 @@ static int sbc_unpack_frame(const u_int8for (ch =0 ; ch < frame->channels; ch++) {for (sb =0 ; sb < frame->subbands; sb++) { levels[ch][sb] = (1 << bits[ch][sb]) -1 ; - scalefactor[ch][sb] =2 << frame->scale_factor[ch][sb]; } }
@@ -534,8 +532,8 @@ static int sbc_unpack_frame(const u_int8for (sb =0 ; sb < frame->subbands; sb++) {if (levels[ch][sb] >0 ) { frame->sb_sample[blk][ch][sb] = - scalefactor[ch][sb] * ((frame->audio_sample[blk][ch][sb] *2.0 +1.0 ) / - levels[ch][sb] -1.0 ); + (((frame->audio_sample[blk][ch][sb] <<1 ) |1 ) << frame->scale_factor[ch][sb])/(float )levels[ch][sb] + - (1 << frame->scale_factor[ch][sb]); }else { frame->sb_sample[blk][ch][sb] =0 ; }
@@ -547,10 +545,11 @@ static int sbc_unpack_frame(const u_int8for (blk =0 ; blk < frame->blocks; blk++) {for (sb =0 ; sb < frame->subbands; sb++) {if (frame->join & (0x01 << sb)) { - frame->sb_sample[blk][0 ][sb] = +double temp = frame->sb_sample[blk][0 ][sb] + frame->sb_sample[blk][1 ][sb]; frame->sb_sample[blk][1 ][sb] = - frame->sb_sample[blk][0 ][sb] -2 * frame->sb_sample[blk][1 ][sb]; + frame->sb_sample[blk][0 ][sb] - frame->sb_sample[blk][1 ][sb]; + frame->sb_sample[blk][0 ][sb] = temp; } } }
Moin,
Am Wed, 18 May 2005 17:31:10 -0600 schrieb Brad Midgley:
Quoted 4 lines
Can I get help with the ranges for bits[ch][sb] in
sbc_unpack_frameand the state.* vectors if they're bounded?How about this first little patch?
This doesn't particularly aid readability so I'd suggest to keep the old code in a comment to explain what it should do. Apart from that it looks fine and you're doing some clever things. So if it improves performance, go ahead.
I thought about it: Do you have long integers on that platform or will they be slow too? Basically there should be no number greater than 2^16 anywhere (I'll have to check that, though) and we only need add, multiply and shift.
A naive fixed point implementation would be to use a 32 bit integers and shift the original value left 16 bits (multiplying by 2^16) leaving 16 bits before and 16 bits after the decimal point. Add and Shift will work as usual, but for multiply additional 16 bits (e.g. an integer type with at least 48 bits) are needed.
Signature · 4 lines
Henryk Plötz Grüße aus Berlin ~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~ ~ Help Microsoft fight software piracy: Give Linux to a friend today! ~
Henryk
Quoted 2 lines
This doesn't particularly aid readability so I'd suggest to keep the old code in a comment
ok
Quoted 4 lines
I thought about it: Do you have long integers on that platform or will they be slow too? Basically there should be no number greater than 2^16 anywhere (I'll have to check that, though) and we only need add, multiply and shift.
32-bit ints are not costly, but >32 probably are too expensive.
Quoted 5 lines
A naive fixed point implementation would be to use a 32 bit integers and shift the original value left 16 bits (multiplying by 2^16) leaving 16 bits before and 16 bits after the decimal point. Add and Shift will work as usual, but for multiply additional 16 bits (e.g. an integer type with at least 48 bits) are needed.
uclibc provides an fp emulation library that is already doing a naive implementation. On a 400mhz pxa255, it works (sort of) for a2dp sink but only if encoding parameters are set low. It doesn't work for a2dp source--it only produces some choppy audio and then drops out completely.
maybe we just need to break floats into two ints. using rationals (numerator/denominator) is what i was thinking when I saw that first fp division by bits[][].
Brad
-------------------------------------------------------
This SF.Net email is sponsored by Oracle Space Sweepstakes Want to be the first software developer in space? Enter now for the Oracle Space Sweepstakes!
http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click
_______________________________________________
Bluez-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
hey
Quoted 1 line
maybe we just need to break floats into two ints. using rationals (numerator/denominator) is what i was thinking when I saw that first fp division by bits[][].
i'm liking this better as i think about it. the precomputed arrays would be changed into rationals too.
one tricky bit will be how and when to normalize the ratio.
brad
-------------------------------------------------------
This SF.Net email is sponsored by Oracle Space Sweepstakes Want to be the first software developer in space? Enter now for the Oracle Space Sweepstakes!
http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click
_______________________________________________
Bluez-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
guys
it's a little bit strange talking about math libraries here :)
i am going to try using gnu mp. it provides rationals and short floats. i will make it an autoconf option so we keep the regular floating point implementation in case that's what you want.
brad
Quoted 12 lines · Brad Midgley
hey
Quoted 1 line
maybe we just need to break floats into two ints. using rationals (numerator/denominator) is what i was thinking when I saw that first fp division by bits[][].
i'm liking this better as i think about it. the precomputed arrays would be changed into rationals too.
one tricky bit will be how and when to normalize the ratio.
brad
Quoted 9 lines
-------------------------------------------------------
This SF.Net email is sponsored by Oracle Space Sweepstakes Want to be the first software developer in space? Enter now for the Oracle Space Sweepstakes!
http://ads.osdn.com/?ad_id=7412&alloc_id=16344&op=click
_______________________________________________
Bluez-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
-------------------------------------------------------
This SF.Net email is sponsored by Yahoo.
Introducing Yahoo! Search Developer Network - Create apps using Yahoo! Search APIs Find out how you can build Yahoo! directly into your own Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
Marcel Holtmann
maintainerHi Brad,
Quoted 5 lines
it's a little bit strange talking about math libraries here :)
i am going to try using gnu mp. it provides rationals and short floats. i will make it an autoconf option so we keep the regular floating point implementation in case that's what you want.
go ahead, but maybe I repeat myself; we need an integer version of the SBC codec. This is where we should head with any optimization. However I am the wrong person for this stuff, but I would welcome everyone who wants to work on it.
Regards
Marcel
-------------------------------------------------------
This SF.Net email is sponsored by Yahoo.
Introducing Yahoo! Search Developer Network - Create apps using Yahoo! Search APIs Find out how you can build Yahoo! directly into your own Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
fwiw,
i think this gives us what you're asking for (indirectly). gnu mp has hand-optimized assembly backends for a few platforms, including arm. it falls back to plain int math for platforms with no targeted assembly.
brad
Quoted 20 lines · Marcel Holtmann
Hi Brad,
Quoted 3 lines
it's a little bit strange talking about math libraries here :)
i am going to try using gnu mp. it provides rationals and short floats. i will make it an autoconf option so we keep the regular floating point implementation in case that's what you want.
go ahead, but maybe I repeat myself; we need an integer version of the SBC codec. This is where we should head with any optimization. However I am the wrong person for this stuff, but I would welcome everyone who wants to work on it.
Regards
Marcel
Quoted 9 lines
-------------------------------------------------------
This SF.Net email is sponsored by Yahoo.
Introducing Yahoo! Search Developer Network - Create apps using Yahoo! Search APIs Find out how you can build Yahoo! directly into your own Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
-------------------------------------------------------
This SF.Net email is sponsored by Yahoo.
Introducing Yahoo! Search Developer Network - Create apps using Yahoo! Search APIs Find out how you can build Yahoo! directly into your own Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005
_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel