Skip to contentSkip to conversation

libsbc optimizing

Bluez-devel Brad Midgley 3 participants 7 messages May 18, 2005 – May 24, 2005 Bluetooth drivers

lore
Share & tools
lore
#0 lore raw

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
diff -u -b -B -w -p -r1.33 sbc.c
@@ -391,7 +391,6 @@ static int sbc_unpack_frame(const u_int8
 	int 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_int8
 	for (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_int8
 			for (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_int8
 		for (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;
 				}
 			}
 		}
#1 lore raw

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_frame and 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! ~
#2 lore raw

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

#3 lore raw

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

#4 lore raw

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

maintainer
#5 lore raw

Hi 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

#6 lore raw

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