Please evaluate my perception of these selectors in DSP/ASM
Posted: Thu Mar 18, 2021 6:46 am
Hello all
I frequently employ the use of multiplexers, selectors, and logic the more I program. This post is examining "2-input 1-output" selectors WRITTEN IN DSP/ASM, with further questions that I hope you can help me with.
Prim Method (visual concept)
There are selectors that I have the code for, that all accomplish the same result based on identical inputs.
Each implementation is the simplest/most optimized way of performing each respective operation I could find on the forum. Each has their orthodox purpose, which I will describe, but my questions are:
- When performing the task coded below, which implementation is the most efficient? (cpu, most important question)
- Which methods introduce latency?
- Which method is the most accurate?
- Which methods will have a higher chance of introducing noise/pop/dropout/break and why?
- Are they all identical? (I think not)
I have experienced problems with stream boolean switches when modulating quickly at sample rate (no hop), which leads me to believe these are all accomplishing the task in a different way (apparent in asm code).
Optimized Selector Method
DSP:
ASM:
^^ pretty straight forward method. In 9 lines of ASM code it compares the selector via cmpps operand against numbers, and outputs a corresponding input. Also has the added bonus of adding inputs, by simply adding dsp lines like:
out=out+in2&(select==2);
out=out+in3&(select==3);
Cool, but bulks it up and we're concerned with 2 ins here.
If Then Else Method
DSP:
ASM:
^^ In 7 lines of ASM this accomplishes the same thing, utilizing cmpps to compare the selector as true or false, then choosing from the 2 inputs based on this. Same thing less code, so more efficient right?
Crossfade Method:
DSP:
ASM:
This method is also only 7 lines of code, but employs multiplication on both inputs-- and outputs the sum.
All of these assume you use a boolean or boolean to mono comparator, or some other cognate code or signal to generate the selector. If clever one could use the input data to generate the control variable.
Now while the first option of the selector lets you have more input options, I typically reach for the ifthenelse out of simplicity and comfort... and after investigation I assume it is more efficient. That being said if my memory serves correct, I've experienced pops/dropouts/straight up failure with certain inputs when modulating quickly on the selector of the first two methods. For this reason I have at times employed the crossfade, sometimes with a gradient to actually crossfade the inputs. When creating complex devices you can imagine this could be problematic if cpu spikes or it becomes unreliable. With it being 7 lines of code I will assume it is as efficient or more than the ifthenelse method, but maybe mulps isn't as efficient as cmpps. What's the better of the two? If the crossfade is best, then would it be better to do it with the stream math functions?
Thanks, hope I informed someone who didn't grasp these tools, and hopefully someone can enlighten me on the details. I'm no expert.
I frequently employ the use of multiplexers, selectors, and logic the more I program. This post is examining "2-input 1-output" selectors WRITTEN IN DSP/ASM, with further questions that I hope you can help me with.
Prim Method (visual concept)
There are selectors that I have the code for, that all accomplish the same result based on identical inputs.
Each implementation is the simplest/most optimized way of performing each respective operation I could find on the forum. Each has their orthodox purpose, which I will describe, but my questions are:
- When performing the task coded below, which implementation is the most efficient? (cpu, most important question)
- Which methods introduce latency?
- Which method is the most accurate?
- Which methods will have a higher chance of introducing noise/pop/dropout/break and why?
- Are they all identical? (I think not)
I have experienced problems with stream boolean switches when modulating quickly at sample rate (no hop), which leads me to believe these are all accomplishing the task in a different way (apparent in asm code).
Optimized Selector Method
DSP:
- Code: Select all
streamin select;
streamin in0;
streamin in1;
streamout out;
out=in0&(select==0);
out=out+in1&(select==1);
ASM:
- Code: Select all
streamin select, in0, in1;
streamout out;
float _F_0=0, _F_1=1;
// Comparison
movaps xmm0,select;
cmpps xmm0,_F_0,0;
// '&' Operator
andps xmm0,in0;
// Assignment to 'out'
movaps out,xmm0;
// Comparison
movaps xmm0,select;
cmpps xmm0,_F_1,0;
// '&' Operator
andps xmm0,in1;
// '+' Operator
addps xmm0,out;
// Assignment to 'out'
movaps out,xmm0;
^^ pretty straight forward method. In 9 lines of ASM code it compares the selector via cmpps operand against numbers, and outputs a corresponding input. Also has the added bonus of adding inputs, by simply adding dsp lines like:
out=out+in2&(select==2);
out=out+in3&(select==3);
Cool, but bulks it up and we're concerned with 2 ins here.
If Then Else Method
DSP:
- Code: Select all
streamin select;
streamin in0;
streamin in1;
streamout out;
out = in1 + (in0 - in1)&(select == 0);
ASM:
- Code: Select all
streamin select, in0, in1;
streamout out;
float _F_0=0;
// '-' Operator
movaps xmm0,in0;
subps xmm0,in1;
// Comparison
movaps xmm1,select;
cmpps xmm1,_F_0,0;
// '&' Operator
andps xmm0,xmm1;
// '+' Operator
addps xmm0,in1;
// Assignment to 'out'
movaps out,xmm0;
^^ In 7 lines of ASM this accomplishes the same thing, utilizing cmpps to compare the selector as true or false, then choosing from the 2 inputs based on this. Same thing less code, so more efficient right?
Crossfade Method:
DSP:
- Code: Select all
streamin select;
streamin in0;
streamin in1;
streamout out;
out = (select*in0)+((1-select)*in1);
ASM:
- Code: Select all
streamin select, in0, in1;
streamout out;
float _F_1=1;
// '*' Operator
movaps xmm0,select;
mulps xmm0,in0;
// '-' Operator
movaps xmm1,_F_1;
subps xmm1,select;
// '*' Operator
mulps xmm1,in1;
// '+' Operator
addps xmm0,xmm1;
// Assignment to 'out'
movaps out,xmm0;
This method is also only 7 lines of code, but employs multiplication on both inputs-- and outputs the sum.
All of these assume you use a boolean or boolean to mono comparator, or some other cognate code or signal to generate the selector. If clever one could use the input data to generate the control variable.
Now while the first option of the selector lets you have more input options, I typically reach for the ifthenelse out of simplicity and comfort... and after investigation I assume it is more efficient. That being said if my memory serves correct, I've experienced pops/dropouts/straight up failure with certain inputs when modulating quickly on the selector of the first two methods. For this reason I have at times employed the crossfade, sometimes with a gradient to actually crossfade the inputs. When creating complex devices you can imagine this could be problematic if cpu spikes or it becomes unreliable. With it being 7 lines of code I will assume it is as efficient or more than the ifthenelse method, but maybe mulps isn't as efficient as cmpps. What's the better of the two? If the crossfade is best, then would it be better to do it with the stream math functions?
Thanks, hope I informed someone who didn't grasp these tools, and hopefully someone can enlighten me on the details. I'm no expert.