if you compile for 32bit the values are very close,The reason for that is, in 64bit the int64 type fits in a register, therefore the variable can be placed in a register whereas in 32bit it cannot (too big). Therefore in 32bit the compiler is somewhat forced into a more "pedestrian" way of incrementing the variable.
but compiling for win64 the values are way off.
@Martin_fr I tried to export the assembly but couldn't find a solution.
So it can be an optimization like it is with 32bitThe 32 bit compilation did not optimize any loop (from what I read).
I tried to change the asm code for a better result, although I like to have more opinion on this, so I can solve such a problem with the help of asm for now, until fpc support this optimization.You already found a reasonably good solution which is the last test case in your test program. Just assign the record field to a variable, use that variable (which the compiler will place in a register) and when the loop is done, move the value of the variable back into the record's field. It's a bit "pedestrian" but, I believe it is preferable over using assembler.
@ASerge I'm afraid I didn't understand exactly your point.I took your last example. I got results:
343Then I added the procedure I had indicated to the end. I got results:
2496
327
2496
2480
2325
And you need to optimize small procedures. For example, let's add this procedure to our sample:It's even inline! However, if you add a Dummy(P) to the end of the Test procedure, the compiler will stop putting the variable P in the register, even in version 3.3.1 with the optimization level -O4.
procedure Dummy(var Value: Int64); inline; begin end;
Would you please report this as a bug with a selfcontained example?In my opinion, this is not a bug. You can't force the compiler to optimize everywhere and always, something must remain for the developer.
Would you please report this as a bug with a selfcontained example?In my opinion, this is not a bug. You can't force the compiler to optimize everywhere and always, something must remain for the developer.
You should leave that to e.g. Florian to decide.Ok - 37282 (https://bugs.freepascal.org/view.php?id=37282).
You already found a reasonably good solution which is the last test case in your test program. Just assign the record field to a variable, use that variable (which the compiler will place in a register) and when the loop is done, move the value of the variable back into the record's field. It's a bit "pedestrian" but, I believe it is preferable over using assembler.
Placing a comment stating the reason for the "acrobatics" with the record's field might be a good idea if someone other than yourself may need to maintain that code.
@PascalDragon the first problem of optimizing usage of a record value needs reporting too?
@PascalDragon the first problem of optimizing usage of a record value needs reporting too?
They did not like it: https://bugs.freepascal.org/view.php?id=34915
You cannot do that acrobatics, when the loop is a for..in loop with a record enumeratorI am not surprised there are cases when that method won't produce the desired results.