FillByte() ist grundsätzliche immer die schnellste Möglichkeit einen Array mit 0/einem konstanten Wert zu befüllen;
Was hindert mich daran, FillDWord zu nehmen, ich weiss ja, das die Array durch 4 teilbar ist.
Code: Alles auswählen
function MatrixIdentity: TMatrix;
var
i: integer;
begin
FillDWord(Result, SizeOf(Result) div 4, 0);
for i := 0 to 3 do begin
Result[i, i] := 1;
end;
end;
Ich habe mir die Original-Quellen angeguckt, der Assembler-Text ist recht lange für diese einfachen Befehle.
Code: Alles auswählen
Procedure FillChar(var x;count:SizeInt;value:byte);assembler; nostackframe;
asm
cmpl $22,%edx { empirically determined value on a Core 2 Duo Conroe }
jg .LFillFull
orl %edx,%edx
jle .LFillZero
.LFillLoop:
movb %cl,(%eax)
incl %eax
decl %edx
jne .LFillLoop
.LFillZero:
ret
.LFillFull:
cld
push %edi
movl %eax,%edi
movzbl %cl,%eax
movl %edx,%ecx
imul $0x01010101,%eax { Expand al into a 4 subbytes of eax}
shrl $2,%ecx
andl $3,%edx
rep
stosl
movl %edx,%ecx
.LFill1:
rep
stosb
.LFillEnd:
pop %edi
end;
{$endif FPC_SYSTEM_HAS_FILLCHAR}
{$ifndef FPC_SYSTEM_HAS_FILLWORD}
{$define FPC_SYSTEM_HAS_FILLWORD}
procedure fillword(var x;count : SizeInt;value : word);assembler;
var
saveedi : longint;
asm
movl %edi,saveedi
movl %eax,%edi
movzwl %cx,%eax
movl %edx,%ecx
{ check for zero or negative count }
cmpl $0,%ecx
jle .LFillWordEnd
movl %eax,%edx
shll $16,%eax
orl %edx,%eax
movl %ecx,%edx
shrl $1,%ecx
cld
rep
stosl
movl %edx,%ecx
andl $1,%ecx
rep
stosw
.LFillWordEnd:
movl saveedi,%edi
end;
{$endif FPC_SYSTEM_HAS_FILLWORD}
{$ifndef FPC_SYSTEM_HAS_FILLDWORD}
{$define FPC_SYSTEM_HAS_FILLDWORD}
procedure filldword(var x;count : SizeInt;value : dword);assembler;
var
saveedi : longint;
asm
movl %edi,saveedi
movl %eax,%edi
movl %ecx,%eax
movl %edx,%ecx
{ check for zero or negative count }
cmpl $0,%ecx
jle .LFillDWordEnd
cld
rep
stosl
.LFillDWordEnd:
movl saveedi,%edi
end;