SynthMaker

Reducing CPU usage/ASM

Archive · 2012 4 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

treacherousumbrella ·

Currently working on quite a CPU intensive audio effect, I'm aware of the usual CPU savings to be had by doing as many calculations as possible in green, reducing graphics refresh rates and stream lining ASM but could do with making savings wherever possible to cut down the CPU use.

Is there any benefit to be had from using the non packed opcodes such as fadd, fmul etc instead of the packed stream opcodes?

How do you convert from the packed stream into mono stream values?

Any other optimisation tips you find useful?

If anyone has a simple example in ASM it would be much appreciated. Thanks 🙂

trogluddite ·

Hi there, If your code is working well using the packed SSE opcodes then switching to the FPU (unpacked) opcodes is unlikely to make your code any faster - even for mono signals where only one channel needs processing. If you are using more than one channel (mono4), it will make things much less efficient, as the processing has to then be done deparately for each stream - requiring a much longer code.

If you have sections of code that are already FPU based (e.g. array access, some maths functions), then you can make some savings by deleting the FPU instructions for any unpacked channels that you aren't using. The unpacked channels are denoted by numbers in square brackets: [0], [1], [2], [3] - the individual channel numbers can only be used with variables, not the xmm registers.

As an example, say you have only two mono signals (e.g. left and right). Seems wasteful to pack and unpack all four values - but assembly can be used to pack and unpack just those two channels...

monoin InL; monoin InR; monoout outL; monoout OutR;

float InPacked=0; float OutPacked=0;

//Pack Inputs fld InL[0]; //Push 1st channel onto the FP stack fstp InPacked[0]; //Pop to 1st channel of variable fld InR[0]; //Push 1st channel to the FP stack fstp inPacked[1]; //Pop to 2nd channel of variable

movaps xmm0,InPacked; //Load packed inputs //DO SOME STUFF movaps OutPacked,xmm0; //Packed Result

//Unpack Outputs fld OutPacked [0]; fstp outL[0]; fld OutPacked[1]; fstp outR[0];

The CPU saving here is very small compared to just using the regular pack and unpack - but I have made good savings with this technique when; (a) there is lots of packing, and (b) values don't change often, so the packing can be hopped. Mostly it is just an example to show how the channel numbers are used - if the main body of the code used any FPU opcodes already, then any instructions using channel {2} or [3] would be fair game for deleting. Hopefully, it also shows why using the FPU is a bad idea when it isn't really needed - as well as all the extra instructions, it always involves a lot of temporary variables. Using the minimum number of variables is always a good idea, as accessing memory (even the cache), costs a lot more CPU cycles than register-only operations - plus extra variables increase the chances of cahe pollution, leading to even slower memory access.

treacherousumbrella ·

Thanks, that's some really useful information and good example code.

Discovered your post on shufps which has helped cut down on a lot of packing/unpacking and also selectors with the jz code.

This post on the wiki seems to suggest that packed calculations are more efficient in almost every circumstance: [old link]

Managed to shave an extra few percent off so thanks again 🙂

trogluddite ·

No problem. 🙂 BTW) One important point for anyone considering editing any FPU instructions - e.g. to remove unused channels. The FPU uses a stack to pass parameters in and out, for example...

fld X[0]; //Pushes a value onto the stack fld Y[0]; fadd; //pops the top two values, adds them, and pushes the result. fstp Sum[0]; //Pops a value off the stack (result of X+Y)

This makes it very easy to crash SM if the number of values pushed isn't the same as the number popped - so take care out there!!

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.