Type
Pmylist = ^ tmylist;
Tmylist = array of word;
Function getminvalue (list: pmylist): word; stdcall;
VaR
Forcount, listcount, I: DWORD;
Maxvaule: int64;
List0address: DWORD;
Begin
Result: = $ 7fff;
Listcount: = high (list ^) + 1;
If (listcount <16) or (listcount mod 16) <> 0) then
Begin
For I: = 0 to listcount-1 do
Begin
If list ^ [I] <result then result: = List ^ [I];
End;
End else
Begin
Maxvaule: = $ 7fff7fff7fff7fff;
List0address: = DWORD (@ list ^ [0]);
Forcount: = listcount Div 16; // 4 * MMX
ASM
Push eax
Push ECx
Push ESI
MoV ESI, list0address // start address
MoV ECx, forcount // Length
Movq mm0, maxvaule
MoV eax, 0
@ Cmploop:
Prefetchnta [ESI + eax + 1024] // fetch ahead by 1024 bytes
Movq MM1, qword [ESI + eax]
Movq mm2, qword [ESI + eax + 8]
Movq mm3, qword [ESI + eax + 16]
Movq mm4, qword [ESI + eax + 24]
Pminsw mm0, MM1
Pminsw mm0, mm2
Pminsw mm0, mm3
Pminsw mm0, mm4
Add eax, 32
Sub ECx, 1
Jnz @ cmploop
Movq MM1, mm0
Psrscsi MM1, $20 // shift right
Pminsw mm0, MM1
Movq MM1, mm0
Psrscsi MM1, $10 // shift right
Pminsw mm0, MM1
Movd eax, mm0
MoV result, ax
Sfence
Emms
Pop ESI
Pop ECx
Pop eax
End;
End;
End;