Since the initial value of the dynamic array in Delphi is not always 0, setlength is used before each use of a one-dimensional array, and then fillchar is generally used for clearing, however, if the array is more than dozens of MB, the efficiency of fillchar is very low. For this reason, I specifically wrote some optimization code for clearing the array or memory.
1. Use the MMX command to optimize the zeroed Memory code:
Procedure zeromemorymmx (Destination: pointer; asize: DWORD );
// EdX, ECx, ESI, EDI, EBP
ASM
Pushad
MoV EDI, destination
MoV ECx, asize
SHR ECx, 3
Lea EDI, [EDI + ECx * 8]
Neg ECx
Pxor mm0, mm0
Pxor MM1, MM1
Pxor mm2, mm2
Pxor mm3, mm3
Pxor mm4, mm4
Pxor MM5, MM5
Pxor mm6, mm6
Pxor mm7, mm7
@ Writeloop:
Movntq qword [EDI + ECx * 8], mm0
Movntq qword [EDI + ECx * 8 + 8], MM1
Movntq qword [EDI + ECx * 8 + 16], mm2
Movntq qword [EDI + ECx * 8 + 24], mm3
Movntq qword [EDI + ECx * 8 + 32], mm4
Movntq qword [EDI + ECx * 8 + 40], MM5
Movntq qword [EDI + ECx * 8 + 48], mm6
Movntq qword [EDI + ECx * 8 + 56], mm7
Add ECx, 8
MoV eax, ECx
Neg eax
CMP eax, 8
Jle @ comm
Jnz @ writeloop
JMP @ end
@ COMM:
@ End:
Sfence
Emms
Popad
End;
2. Reset the Memory code optimized using the rep command:
Procedure zeromemoryrep (Destination: pointer; Length: DWORD); stdcall;
ASM
Pushad
XOR eax, eax // write data
MoV ECx, length // get the length
MoV EDI, destination // target pointer
Rep stosb
Popad
End;
The above two codes have been tested and found that the efficiency of using MMX on 50 m is higher than that of using rep. Rep is recommended for 50 m.