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 // 开始地址
mov ecx, ForCount // 长度
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
PSRLQ MM1,$ 20 // 右移
PMINSW MM0,MM1
MOVQ MM1,MM0
PSRLQ MM1,$ 10 // 右移
PMINSW MM0,MM1
Movd eax,mm0
Mov Result,AX
Sfence
Emms
pop esi
pop ecx
pop eax
end ;
end ;
end ;
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 // 开始地址
mov ecx, ForCount // 长度
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
PSRLQ MM1,$ 20 // 右移
PMINSW MM0,MM1
MOVQ MM1,MM0
PSRLQ MM1,$ 10 // 右移
PMINSW MM0,MM1
Movd eax,mm0
Mov Result,AX
Sfence
Emms
pop esi
pop ecx
pop eax
end ;
end ;
end ;