<font color='black' size='2' face='arial'><font size="2"> </font><font size="2"><font face="Arial, Helvetica, sans-serif">Thank you Sven. <br>
Unfortunately I can't find a way to compress the information in few lines without losing important information. I've already done that mistake in the first mail, now I'll try to fully explain why I'm interested in the way these registers are allocated. Even if the mail is long I've tried to write it as readable as possible. I'll try to explain, step by step, with the help of 3 versions of a common function. I've chosen the "pos" function.<br>
<br>
<br>
HERE IS THE ORIGINAL VERSION. YOU CAN SKIP THE PASCAL CODE.<br>
{Elapsed time for this function in tests:6830ms.<br>
# Var $result located in register r14<br>
# Var i located in register rbx<br>
# Var MaxLen located in register r13<br>
# Var pc located in register r12<br>
Temps allocated between rsp+16 and rsp+48}<br>
Function PosORIGINAL(Const Substr : AnsiString; Const Source : AnsiString) : SizeInt;<br>
var<br>
i,MaxLen : SizeInt;<br>
pc : pchar;<br>
begin<br>
RESULT:=0;<br>
if Length(SubStr)>0 then<br>
begin<br>
MaxLen:=Length(source)-Length(SubStr);<br>
i:=0;<br>
pc:=@source[1];<br>
while (i<=MaxLen) do<br>
begin<br>
inc(i);<br>
if (SubStr[1]=pc^) and<br>
(CompareByte(Substr[1],pc^,Length(SubStr))=0) then<br>
begin<br>
RESULT:=i;<br>
exit;<br>
end;<br>
inc(pc);<br>
end;<br>
end;<br>
end;<br>
<br>
<br>
HERE COMES THE FIRST MODIFIED VERSION OF THE ORIGINAL FUNCTION. </font></font><font size="2"><font face="Arial, Helvetica, sans-serif"><font size="2"><font face="Arial, Helvetica, sans-serif">YOU CAN SKIP THE PASCAL CODE.<br>
</font></font>{Compared with PosORIGINAL, variable "MaxLen" has been removed, the "while" loop has been replaced with a "for" loop and "if Length(SubStr)>0 then" is replaced by "if Length(SubStr)<>0 then".<br>
Elapsed time for this function in tests:6000ms. That's ~800ms faster than original function.<br>
# Var $result located in register r12<br>
# Var pc located in register r14<br>
# Var I located in register rbx<br>
Temps allocated between rsp+16 and rsp+48}<br>
{Function PosFASTER(Const Substr:AnsiString; Const Source:AnsiString):SizeInt;<br>
var pc:pchar;<br>
I:SIZEINT;<br>
begin<br>
if Length(SubStr)<>0 then<br>
begin<br>
pc:=@source[1];<br>
for I:=1 to (Length(source)-Length(SubStr)+1) do<br>
if (SubStr[1]=pc^)and(CompareByte(Substr[1],pc^,Length(SubStr))=0) then exit(I) else inc(pc);<br>
end;<br>
RESULT:=0;<br>
end;}<br>
<br>
<br>
HERE COMES THE VERSION I'D LIKE TO RUN FASTEST. </font></font><font size="2"><font face="Arial, Helvetica, sans-serif"><font size="2"><font face="Arial, Helvetica, sans-serif">YOU CAN SKIP THE PASCAL CODE.<br>
</font></font>{Compared with function PosFASTER, variable "I:SIZEINT" has been removed and replaced with "result".<br>
Elapsed time for this function in tests:6600ms. WHICH IS NOT WHAT I WANTED!!!<br>
# Temps allocated between rsp+16 and rsp+40<br>
# Var $result located in register r13<br>
# Var pc located in register rbx}<br>
Function PosWISHTORUNFASTEST(Const Substr:AnsiString; Const Source:AnsiString):SizeInt;<br>
var pc:pchar;<br>
begin<br>
if Length(SubStr)<>0 then<br>
begin<br>
pc:=@source[1];<br>
for RESULT:=1 to (Length(source)-Length(SubStr)+1) do<br>
if (SubStr[1]=pc^)and(CompareByte(Substr[1],pc^,Length(SubStr))=0) then exit else inc(pc);<br>
end;<br>
RESULT:=0;<br>
end;<br>
<br>
<br>
CONCLUSION<br>
The second version(PosFASTER) runs noticeable faster(6000ms.) compared to the original version(6800ms). I wish the third version(PosWISHTORUNFASTEST) to run even faster(less than 6000ms in my tests). Why? Because by removing the variable "I:SIZEINT;" I consider I make the job easier to the compiler. Instead of running faster, the third version(PosWISHTORUNFASTEST) runs significantly slower(6600ms) than the second version(PosFASTER)(6000ms). There are two possible reasons for this slowdown:<br>
1)I hit the "if...then...else" anomaly again, but I strongly doubt this is the reason of the slowdown.<br>
2)Using r13("result") is slower than rbx("I"). If this is the case then I'd like a solution for these situations. In my mind I have three approaches:<br>
a) When function result is used in a "for" loop, try to assign a "better" register.<br>
b) If the first approach is not good, then give the programmer the chance to act as a child: I would like one of these registers for a variable, or I don't want a register in the r12-r15 range for the function result. I think C has a directive "register" for variables, I don't know much about it.<br>
c) If none of the above is ok, then please explain how can I identify the functions that can use the result in "for" loops without penalties regarding speed. For example I've noticed that if a function doesn't contain a call to another function or procedure than, a int64 result is returned in rax, not r12, which should be ok for me, see "Function Pos(c : Char; Const s : AnsiString) : SizeInt;".<br>
<br>
I'm not much interested in "while" loops as I'm interested in "for" ones. I hope I've explained better this time.<br>
Thank you for patience.</font></font><br>
<div style="font-family:arial,helvetica;font-size:10pt;color:black">
<div id="AOLMsgPart_0_ba32a5b0-9f44-4472-819d-493de2f82821" style="margin: 0px;font-family: Tahoma, Verdana, Arial, Sans-Serif;font-size: 12px;color: #000;background-color: #fff;">
</div>
<!-- end of AOLMsgPart_0_ba32a5b0-9f44-4472-819d-493de2f82821 -->
</div>
</font>