Skip to main content
gamedev.net
🔒 Locked

Memory Stall

Started by _psi 2 replies 1.1k views
Original Post
_psi
_psi
Hello all, i'm trying to recode some of my time critical code in assembler. After recoding it & profiling i noticed that three key instructions take 96% of time, namely 3 register-->memory writes: mov dword ptr [edi],edx ..change edi... mov dword ptr [edi],edx ..change edi... mov dword ptr [edi],edx I assume this must be a memory stall of some sort.I'm confused though, because i thought that since i dont reuse the value i'm writing, the procesor doesn't have to wait for the piece of data to be retrieved from memory (like in the case of a memory-->register read) - but it would just send it off - why does it still take so long ? What can i do about it ? Thanks for any clues, Mike
JesseT
JesseT
When you modify a register (write), and the next instruction relies on the value of that register (read), the instruction must first wait for the modification instruction to complete. In your case, it looks like you're incrementing/decrementing edi, and then using the value of edi as the address to write a 32-bit value to. It also looks like this code is the innards of an unrolled inner-loop.

I would first suggest using an integer offset, and then incrementing edi by the total amount. For example:

; edi contains starting address; ecx contains number of iterations; edx contains value to writeinner_loop:    mov dword ptr [edi],edx    mov dword ptr [edi + 4],edx    mov dword ptr [edi + 8],edx    mov dword ptr [edi + 12],edx    add edi,16    dec ecx    jnz inner_loop


Another possibility that you in fact raised was the prospects of encounting a cache miss. Look into using the cache prefetch instructions with MMX/3DNow!/SSE/SSE2/SSE3. I haven't written much x86 assembly recently, so I couldn't tell you how to use it properly.
chollida1
chollida1
You didn't mention what the underlying data you were operating on but linked list's in general are a culprit for things like this where you get the next ptr, which isn't in the cache, modify it and repeat.

In that case you spend more time waiting for the CPU to get the memory for hte next node than you do operating on it, epecially for very small operations.

To verify try chanigng your data so its in an array or some other type of contiginous data structure.
CheersChris
pjcast
pjcast
What you have here is an AGI stall...

http://www.azillionmonkeys.com/qed/pentopt.html

9. Address generation interlock (PPlain and PMMX)
It takes one clock cycle to calculate the address needed by an instruction which accesses
memory. Normally, this calculation is done at a separate stage in the pipeline while the
preceding instruction or instruction pair is executing. But if the address depends on the
result of an instruction executing in the preceding clock cycle, then you have to wait an
extra clock cycle for the address to be calculated. This is called an AGI stall.

Example:
ADD EBX,4 / MOV EAX,[EBX] ; AGI stall
The stall in this example can be removed by putting some other instructions in between
ADD EBX,4 and MOV EAX,[EBX] or by rewriting the code to:
MOV EAX,[EBX+4] / ADD EBX,4

You can also get an AGI stall with instructions which use ESP implicitly for addressing, such
as PUSH, POP, CALL, and RET, if ESP has been changed in the preceding clock cycle by
instructions such as MOV, ADD, or SUB. The PPlain and PMMX have special circuitry to
predict the value of ESP after a stack operation so that you do not get an AGI delay after
changing ESP with PUSH, POP, or CALL. You can get an AGI stall after RET only if it has an
immediate operand to add to ESP.

Examples:
ADD ESP,4 / POP ESI ; AGI stall
POP EAX / POP ESI ; no stall, pair
MOV ESP,EBP / RET ; AGI stall
CALL L1 / L1: MOV EAX,[ESP+8] ; no stall
RET / POP EAX ; no stall
RET 8 / POP EAX ; AGI stall

The LEA instruction is also subject to an AGI stall if it uses a base or index register which
has been changed in the preceding clock cycle. Example:
INC ESI / LEA EAX,[EBX+4*ESI] ; AGI stall

PPro and PII have no AGI stalls for memory reads and LEA, but they do have AGI stalls for
memory writes. This is not very significant unless the subsequent code has to wait for the
write to finish.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.