question about altivec registers
Gabriel Paubert
paubert at iram.es
Wed Oct 27 23:21:50 EST 1999
On Wed, 27 Oct 1999, Adrian Cox wrote:
> Linux on PowerPC should end up doing a classic lazy save/restore for the
> vector context, as it already does for the floating point registers. On
> SMP systems this simple approach isn't possible, but a quick
> approximation is to detect the first time a process uses Altivec, and
> marking it to always save and restore vector context from then on.
Agreed.
> I'd recommend that compiler writers use the vrsave register to mark
> which vector registers they use, as a precaution against future kernels
> which may look at this. Note that the G4 is extremely fast at linear
> sequences of cacheable stores (store miss merging), and it is probably
> cheaper for the kernel to ignore vrsave and avoid branches in the save
> and restore sequence. Of course, it is correct to simply set every bit
> in vrsave at the start of your application, and never change it again.
> It may be non-optimal on future systems, but it should remain correct.
Don't forget nevertheless a worthwhile optimization: that VRSAVE=0 means
that the program has no active Altivec registers at the time so that the
save can be skipped altogether (except for vrsave and the control/status
register).
And why would you want to use a bitmap ? This seems braindead to me, put a
value between 0 and 32 in vrsave. Since all registers are identical
in use and purpose, save registers 0 to n. Disclaimer: I've not seen if
the ABI specifies how and which Altivec registers are saved restored
across calls.
Paranoid point of view: the restore must reload all altivec registers
(or clear the ones which are not specified as used by VRSAVE), otherwise
you might leak the contents of the Altivec registers of another process.
I'm not a security expert, but I don't like this possibility at all.
Code bloat concerns: actually to save or restore a single altivec
register, you need 2 instructions given the available addressing modes:
this makes 512 bytes of code for 32 register save + 32 register restore
(there are ways to slightly reduce it but there is also the overhead of
setting up several integer registers, saving vrsave and the control/status
register...). Count 12 bytes/register if you use a bit in vrsave to check
every register. But the branches are not that expensive if the cr bits are
set enough in advance: assuming vrsave has been copied to r0:
cmpwi r0,0
bne- done
mtcrf 0x1,r0
la r3,vregsavearea+448
li r4,16
li r5,32
li r6,48
bf 31,30f
stvx v31,r6,r3
30: mtcrf 0x2,r0
bf 30,29f
stvx v30,r5,r3
29: srwi r0,r0,8
bf 29,28f
stvx v29,r4,r3
28: bf 28,27f
stvx v28,0,r3
27: addi r3,r3,-64
bf 27,26f
stvx v27,r6,r3
26: mtcrf 0x1,r0
bf 26,25f
stvx v26,r5,r3
25: bf 25,24f
stvx v25,r4,r3
24: bf 24,23f
stvx v24,0,r3
23: addi r3,r3,-64
bf 31,22f
stvx v23,r6,r3
22: mtcrf 0x2,r0 # Cycle since 30: repeats here
bf 30,21f
stvx v22,r5,r3
21: srwi r0,r0,8
bf 29,20f
...
0: bf 24,done
stvx v0,0,r3
done: # now save the control/status register...
in this code the bits to test are always set or moe 3 branches ahead of
the test by interleaving 2 cr fields set up by mtcrf according to vrsave
bits. But the code is significantly larger than using a count and
branching at the right place in the save routine.
> As for the cache thrashing effect, remember that 512 bytes going in and
> out of the L2 cache is not very expensive, and that there is probably 1
> or 2MB of L2 fitted.
My feeling is that it is unlikely that the code is in the L1 cache, this
code is not a tight loop which is executed 1000 times in a row, and it is
probably saturating L2 cache bandwidth. If you need 8 bytes of code and 16
bytes of data for each register save/load on average, it's 3 L2 data beats
or 6 clocks in the most common scenario (L2 at 1/2 core frequency).
Gabriel.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list