|
| Notices |
Welcome to the DriverHeaven.net forums. You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our community today! If you have any problems with the registration process or your account login, please contact contact us. |
 |
Feb 19, 2007, 06:21 PM
|
#1
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Using accum...
Is 'accum' treated differently in a 'macs' instruction and a 'macints' instruction, and if so, how?
The reason I ask is that I am getting different results using 2 seemingly equivalent instructions:
; the following three sets of instructions work as expected and have same result
macs tmp, 0, x, y;
macs r, temp, x, 0x80000000;
macs tmp, 0, x, y;
macints r, tmp, x, 0xFFFFFFFF;
macs 0, 0, x, y;
macs r, accum, x, 0x80000000;
; this one has a different result (saturates)
macs 0, 0, x, y;
macints r, accum, x, 0xFFFFFFFF;
It is looking as though 'accum' should not be used with a 'macints' instruction, but I do not recall this being documented anywhere (I thought that the only restriction was that it could only be used as an 'A' operand).
Also, are there any restricitions on using 'accum' in consecutive instructions?
The reason I ask is because (again) I am getting unexpected results:
; r1 and r2 have different results (when I expect them to be equal)
; r1 has the expected result, while r2 does not
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r1, accum, x2, y2;
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r2, accum, x2, y2;
Additionally, if I add an instruction in between the above, 'r1' and 'r2' then appear to have the correct result, but the result of the instruction in between appears to be wrong (even an instruction like 'macs r3, 0, 0, 0', where you would expect 'r3' to equal 0).
i.e. (to be clear)
; r1 and r2 have expected result, while r3 does not
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r1, accum, x2, y2;
macs r3, 0, 0, 0;
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r2, accum, x2, y2;
BTW: Testing was done on a 10k1 card (in case this is another 10k1 only anomaly).
-Russ
Last edited by Russ; Feb 19, 2007 at 11:36 PM.
|
|
|
Feb 19, 2007, 11:16 PM
|
#2
|
|
S-3D enthusiast
Join Date: Sep 2004
Location: Canada
Posts: 1,410
|
I found this post from Max M. about not using macints.
|
|
|
Feb 19, 2007, 11:23 PM
|
#3
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Thanks Tril,
I had thought I had read somewhere, that there was another restriction with using 'accum', but could not remember where I had read about it (and did not recall it being associated with the 'macints' instruction).
So that just leaves the second part of the post...
BTW: Max, eyagos, Tiger, whom-ever is currently maintaining the beginner's DSP guide, can you add that info to the guide?
Last edited by Russ; Feb 19, 2007 at 11:29 PM.
|
|
|
Feb 20, 2007, 03:07 PM
|
#4
|
|
kX user
Join Date: Apr 2004
Posts: 851
|
Good idea, that guide needs a lot of corrections and additions.
I'll edit it as soon as I find time.
|
|
|
Feb 20, 2007, 03:52 PM
|
#5
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Thanks Tiger,
It is good to hear from you 
|
|
|
Feb 21, 2007, 05:55 PM
|
#6
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
Well, actually it's not like we "may not" use the accum in macints - we "may" - it just won't do what we expect it to do - so actually we "don't want" to use it.
The trick is that the ALU differentiates fractional/integer MAC instructions not at (or just right after) multiplication stage (as we're accustomed to think of it - as it makes things easier) - but the real difference seems to be in the way ALU flushes accumulator's value to the R register (and the way A operand is written to accum (if A is not being accum itself)).
I've tried t write down the actual MAC* operation in pseudocode and here's what i've got
(simplified - w/o saturation):
Code:
<MAC*>
if (A is not ACCUM) then
ACCUM[66:63] <- sign_bits(A)
ACCUM[62:31] <- A
ACCUM[30:0] <- 0
fi
ACCUM <- ACCUM + (X * Y)
R <- ACCUM[62:31]
<MACINT*>
if (A is not ACCUM) then
ACCUM[66:32] <- sign_bits(A)
ACCUM[31:0] <- A
fi
ACCUM <- ACCUM + (X * Y)
R <- ACCUM[31:0]
So no wonder that
(1)
macs tmp, 0, x, y
macints r, tmp, x, 0xFFFFFFFF
and
(2)
macs 0, 0, x, y
macints r, accum, x, 0xFFFFFFFF
give different results - they Are very different beasts.
actually, code (2) does pretty the same job as
macints tmp, 0, x, y
macints r, tmp, x, 0xFFFFFFFF
(if we're not counting saturation of course)
---
here are three examples that may help to understand (and proof) those 'operation pseudocodes' above
Code:
static a = 0x123
static b = 0x123
static c, d
macs c, 0, a, b ; c = 0
macints d, accum, 0, 0 ; d = 0x14ac9 !
end
Code:
static a = 0x123
static b = 0x123
static c, d
macints c, 0, a, b ; c = 0x14ac9
macs d, accum, 0, 0 ; d = 0 !
end
fun one:
Code:
static a = 0x123
static b = 0x123
static c, d, e
macs c, 0x1, a, b ; c = 0x1 (accum = 0x100014ac9)
macints d, accum, 0, 0 ; d = 0x7fffffff (0x100014ac9 saturated at [31:0])
macs e, accum, 0, 0 ; e = 0x1 (again :)
end
======================
Accum mysteries @ K1 - i recall also the following thread: microcode anomoly?
So yeah, accum use on K1 sometimes fails (under some really unknown circumstances). For me it seems to be just a sort of bug in hardware.
Last edited by Max M.; Feb 22, 2007 at 05:20 AM.
|
|
|
Feb 21, 2007, 06:16 PM
|
#7
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Thanks for the explanation Max 
Good info as always...
As for the 10k1 anomalies, I wish I could figure out exactly what is happening, as it makes it a little hard to optimize the code, when you have to confirm that it is doing what it is supposed to do, everytime I use the accum instruction. However, if it is indeed some hardware bug, I guess I am out of luck. I didn't really expect an answer with that anyway, but mainly wanted to document another situation where I see it happening, so that I (and other peple) can see which situations might give them trouble, etc.
|
|
|
Feb 21, 2007, 10:32 PM
|
#8
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
BTW: In both cases (with the anomalies), the manner in which the result is off, follows a similar pattern, so there does seem to be some logic to it.
i.e.
Code:
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r1, accum, x2, y2;
macs r3, 0, 0, 0;
macs 0, 0, x0, y0;
macs 0, accum, x1, y1;
macs r2, accum, x2, y2;
If the 'R' param is 0 in the first (highlighted) instruction, the result of that instruction is added to the second (highlighted) instruction ('r3' is the result of the first (highlighted) instruction). If the 'R' param in the first (highlighted) instruction is a register, then the code acts as you would expect it to ('r3' = 0).
So maybe there is some intended design here, but if so, I wonder why it would be different in the 10k2 design?
|
|
|
Feb 21, 2007, 11:37 PM
|
#9
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
mmm, that makes sense... sure, it should be some pattern (even if it is hardware bug)
unfortunately, i can't investigate it in any way since i've fried my Live! somewhere in 2003... ;(
btw. that buggy fxmix code was something like:
Code:
....
macs tmp, tmp, in5_l, In5Level;
macs 0, 0, tmp, FX1;
macs out_l1, accum, mono_in1, FX1;
macs 0, 0, tmp, FX2;
macs out_l2, accum, mono_in2, FX2;
...
and signal controlled by FX1 was bleeding to out_l2 somehow
so yeah, it looks similar (a sort of)...
>So maybe there is some intended design here, but if so, I wonder why it would be different in the 10k2 design?
yeah, i doubt such crazy stuff was really intended, so of course it looks more like "it was not intended and therefore fixed in k2" :) who knows... (well, i know who knows - but... :))
So, how do you think - preliminary - can we say that for K1 it is better to avoid using a combination of "writing to 0" and "using accum in subsequent instructions"?
Last edited by Max M.; Feb 22, 2007 at 12:09 AM.
|
|
|
Feb 22, 2007, 03:29 AM
|
#10
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Quote:
Originally Posted by Max M.
yeah, i doubt such crazy stuff was really intended, so of course it looks more like "it was not intended and therefore fixed in k2"  who knows... (well, i know who knows - but...  )
|
Yeah, thats true... Even if a bug somehow proves useful, it is still a bug.
Quote:
Originally Posted by Max M.
So, how do you think - preliminary - can we say that for K1 it is better to avoid using a combination of "writing to 0" and "using accum in subsequent instructions"?
|
With the previous anomaly (that you posted the link for (above)), the 'accum' instruction was not even involved. I am thinking that the 'accum' instruction is not the culprit here either, and again, the problem is with leaving the "R" param zero. Maybe this is not a good idea to do on k1 models, unless we are willing to manually verify that it is working as we expect, in our code that uses it (and that it will not have any effect on plugins connected to our plugin, etc (i.e. I seem to recall one case where one plugin was bleeding into another one, and I would be willing to bet that it is related to this issue)). Additionally, using a register (temp or whatever), as the "R" param, even if it is not used for any purpose (other than to prevent this problem), does not effect the useful of using 'accum' (i.e. leaving the "R" param zero (in the previous instruction), does not seem to be a requirement of using the 'accum' instruction (guard bits still work, etc)). The only drawback is that in some cases, you might need one extra GPR for this purpose, but that is not so bad.
Last edited by Russ; Feb 22, 2007 at 03:53 AM.
|
|
|
Feb 22, 2007, 05:33 AM
|
#11
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
On a side note: While thinking about this, I had an idea regarding 'temp' registers. It seems to me (correct me if I am wrong) that it should be possible to have some global temp registers (i.e. temp registers that can be used by all plugins). If some GPR's were reserved for such a purpose, it seems that it could cut down on the total number of GPR's used overall, as each plugin would not have to create it's own temp registers (for those plugins that use them anyway).
What do you think?
|
|
|
Feb 22, 2007, 12:27 PM
|
#12
|
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 3,721
|
My recent re-study made this easy for me to find.
Quote:
|
2.Static and temp registers. They are used for storing intermediate data during instruction execution. The value of a static register is preserved until it is overwritten (next sample cycle), or the microcode is reinitialized (reloading or resetting the plugin). Temp registers are used for the present sample cycle only, so their last value can not be used in the next cycle it will be zero. The idea behind the temp register is that it can be shared by all loaded effects, but such sharing is not supported by kX at the present time, so it is recommended that static be used most of the time. Despite that we'll use temp registers in the examples for learning purposes only.
|
I suspect - this wont ever become possible as I would think it would 'break' existing plugins, (needs changing all the 'temps' currently used - to 'static's and re-init their values for 'current sample' needs.. ??) so - Im thinking a new instruction would be needed to avoid such 'breaking' - I thought I seen that DANE was 'interpreted' and not a 'direct' DSP assembler, so suspect a new instruction would be 'possible'.
Ok - I shut up now.... 
|
|
|
Feb 22, 2007, 05:01 PM
|
#13
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
>temp registers.
this is how is supposed to be from the beggining. Temp registers should be global (Creative, Emu and all Linux loaders support this - only kX loader s...s  )
Moreover, const registers may be global too.
>as I would think it would 'break' existing plugins
No, it won't.
|
|
|
Feb 22, 2007, 05:31 PM
|
#14
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
@Maddogg6,
By the very nature of a temp variable, you make no assumptions of it's initial value.
i.e.
Your first instructions that uses it, uses it as the "R" param, thus overwriting its current value (so it's initial value really makes no difference).
@Max,
Yeah, I didn't think about constants, but I suppose if 2 (or more) plugins use the same (non-hardware) constant, then making them global, would also save some GPRs.
Out of curiousity, if this was intended from the beginning, why is it not being done?
|
|
|
Feb 22, 2007, 05:43 PM
|
#15
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
>Out of curiousity, if this was intended from the beginning, why is it not being done?
That's the question. Since the loader is part of the driver - it's all up to E. to implement whatever he thinks to be important. So at earlier stages of development we could go without good loader but later there were too many other thing to do. No wonder a DSP stuff had lowest priority - E., personally, has no interest in dsp programming.
(Well, strictly speaking if we analyse a benefit of using shared temps - it would not be so big, less then ~20 gprs save for typical DSP setup. Although there're some situations where both temps and consts could give much bigger benefit - for example - with 2 EQG10 loaded, a shared constants would save about 30 gprs (60 for three instances and so on...).)
Last edited by Max M.; Feb 22, 2007 at 05:57 PM.
|
|
|
Feb 22, 2007, 06:12 PM
|
#16
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
I understand... It is too bad as for us 10k1 users, every extra GPR helps....
|
|
|
Feb 22, 2007, 06:44 PM
|
#17
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
it is never late. Finally, why a few ZS Notebook owners have more priority then a mājor kX contributers? (hehe, just kidding of course - but...)
|
|
|
Feb 22, 2007, 06:51 PM
|
#18
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Hehe, well considering E. has a ZS Notebook himself (IIRC)...
And I cannot complain as I was in a similair situation with my rear channels not working on my SB022x model...
|
|
|
Feb 22, 2007, 09:43 PM
|
#19
|
|
Tail Razer
Join Date: Jun 2005
Location: Bernyurass, AZ - USA
Posts: 3,721
|
Quote:
>as I would think it would 'break' existing plugins
No, it won't.
|
Ok - I guess Im completely lost...
Say 2 plugins are using a 'temp' register called 'V1'
If 'temp' (and as it turns out - 'const' too) become global...
Wouldn't they interfere with each other - and require changing them to 'statics' ???
I guess I thought I was understanding somethings ...maybe not... ??
edit: it would also just seem to make more sense to me to make a 'global' register - if DANE is infact 'interpreted' ... no?
|
|
|
Feb 22, 2007, 11:24 PM
|
#20
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Remember that all of the code for all the plugins (the entire DSP) is executed sequentially, so there is no chance for another plugin to change the value of your temp variable while your plugin is using it.
Also, do not forget, that all we are really taking about here is an address. i.e. 'temp' points to address xxxx. 'Global' in this respect, just means that all plugins can use this address to store temporary data (and again, it is temporary data, i.e. is only valid for one sample cycle, and it is only valid to your plugin, during the time your plugin's code is being executed).
As for constants, well it is a constant value, so a plugin cannot change its value.
BTW: Do not get confused between the Dane interpreter, and the plugin loader.
Last edited by Russ; Feb 23, 2007 at 12:04 AM.
|
|
|
Feb 23, 2007, 11:07 PM
|
#21
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
btw. kX's loader is the first candidate to go open source. So maybe it's time.
(i've already gave my permission for the Dane to be open - although ii'm not happy about that since the Dane sources suck)
the main problem is that it is in the kernel.
|
|
|
Feb 23, 2007, 11:32 PM
|
#22
|
|
S-3D enthusiast
Join Date: Sep 2004
Location: Canada
Posts: 1,410
|
Quote:
|
Originally Posted by Max M.
although ii'm not happy about that since the Dane sources suck
|
As long as the comments and the variable names are not in Russian it should not be too bad.
Quote:
|
Originally Posted by Max M.
the main problem is that it is in the kernel.
|
Can you explain that please.
|
|
|
Feb 23, 2007, 11:43 PM
|
#23
|
|
d/h member-shmember
Join Date: Dec 2002
Location: from the edge of the deep green sea
Posts: 2,207
|
hehe. there're no comments at all  to be honest i shame of it - it is my first C programe ("Hello World!").
>Can you explain that please.
Yes, sure - as you probably know the driver programming is very different from those higher level application programming - it has so many restrictions and so many limits that no one can be happy with it. So despite problems with debugging (never tried to debug kernel? hehe - i envy you) - it is the problem with implemention - it is really unclear how we actuallly can make some parts of kX open without making every source code line to be open.
Ah - bad expalnation - i'll go further lately
Last edited by Max M.; Feb 23, 2007 at 11:53 PM.
Reason: sorry, bad english
|
|
|
Feb 24, 2007, 04:40 AM
|
#24
|
|
DriverHeaven Extreme Member
Join Date: Jan 2005
Posts: 4,104
|
Quote:
Originally Posted by Tril
As long as the comments and the variable names are not in Russian it should not be too bad.
|
lol
|
|
|
Feb 24, 2007, 09:08 AM
|
#25
|
|
kX Project Lead Programmer and Coordinator
Join Date: Dec 2002
Posts: 2,953
| |