https://bugs.freepascal.org/view.php?id=35775
I'm both honoured and amused! Thank you.
Gareth aka. Kit
---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Mailing lists / fpc-devel / 2019-06
21 messages · 9 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
https://bugs.freepascal.org/view.php?id=35775
I'm both honoured and amused! Thank you.
Gareth aka. Kit
---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
J. Gareth Moreton wrotehttps://bugs.freepascal.org/view.php?id=35775 I'm both honoured and amused! Thank you.
Well, it was meant seriously. You mentioned more than once that you like optimizations. This one would be a real big improvement for a pattern that is often encountered.
It's also probably technically challenging, so you will learn a lot (or so I assume).
Seems like a perfect fit to me...
Michael.
I figured you were serious with it. I've garned a reputation, it seems!
I have some organisation to figure out first, since I've got to fix a bug <https://bugs.freepascal.org/view.php?id=32913>, begin development of pure functions and update my patches for the x86-64 optimiser overhaul so it will still merge.
Granted, loop optimisaion is something that's cropped up a few times, both in terms of vectorisation and also taking advantage of pure functions. I can't promise anything, but I'll certainly take a look.
As for learning new things... it's true. I learnt so much about nodes while developing the XML node dump feature.
Gareth
---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
https://bugs.freepascal.org/view.php?id=35775 I'm both honoured and amused! Thank you.…
Hi Gareth,
there are more optimizations to look at
An user could write custom string enumerators to replace such assignments in loops and try to manually solve that issue.
But then
https://bugs.freepascal.org/view.php?id=34915
the enumerators are stored in memory rather than registers, so it is always slower than a normal loop
Or since you like case; a case of strings should use a hashmap or something rather than doing one by one comparisons
Cheers,
Benito
One thing I have been considering is to promote fields and global variables to local registers to reduce memory accesses. However, it would make multi-threaded code a bit trickier to write and demand the use of the "volatile" intrinsic on things like the conditions of while loops.
Before I start anything though, I need to put together a schedule or a to-do list to work out what to play with first. A lot of the time, I go by my whims and think "I fancy playing with the Free Pascal Compiler today" or I see something and think 'I could improve that' - unfortunately it's led me to mix fixes and changes into the same patch, which has been problematic before, so I'm trying to be more disciplined about it.
Gareth aka. Kit
J. Gareth Moreton schrieb am Do., 27. Juni
2019, 12:18:
I think having record fields in registers would already go a long way. Global variables aren't used /that/ often in modern, object oriented code anyway.
Regards,
Sven
One thing I have been considering is to promote fields and global variables to local…
J. Gareth Moreton schrieb am Do., 27. Juni 2019, 12:18: I think having record fields in…
On Thu, Jun 27, 2019 at 8:15 AM Sven Barth via fpc-devel <
Aren't they already?
<https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:pascal,source:'unit+output%3B%0A%0A%7B$mode+ObjFPC%7D%7B$H%2B%7D%0A%7B$ImplicitExceptions+Off%7D%0A%0Ainterface%0A%0Auses+SysUtils%3B%0A%0Atype+%0A++TRec+%3D+record%0A++++A:+LongInt%3B%0A++++B:+Double%3B%0A++++C:+String%5B8%5D%3B%0A++++D:+Boolean%3B%0A++end%3B%0A%0Avar+R:+TRec+%3D+(A:+1%3B+B:+2.35%3B+C:+!'ABCDEFGH!'%3B+D:+True)%3B%0A%0Aprocedure+TakesARecordByValue(Rec:+TRec)%3B%0Aprocedure+TakesARecordByReference(constref+Rec:+TRec)%3B%0A%0Aimplementation%0A%0Aprocedure+TakesARecordByValue(Rec:+TRec)%3B%0Abegin%0A++with+Rec+do+%0A++++WriteLn(Format(!'%5BA:+%25d,+B:+%25f,+C:+%25s,+D:+%25d%5D!',+%5BA,+B,+C,+Ord(D)%5D))%3B%0Aend%3B%0A%0Aprocedure+TakesARecordByReference(constref+Rec:+TRec)%3B%0Abegin%0A++with+Rec+do+%0A++++WriteLn(Format(!'%5BA:+%25d,+B:+%25f,+C:+%25s,+D:+%25d%5D!',+%5BA,+B,+C,+Ord(D)%5D))%3B%0Aend%3B%0A%0Aend.%0A'),l:'5',n:'0',o:'Pascal+source+%231',t:'0')),k:55.826666565704016,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:fpc304,filters:(b:'0',binary:'1',commentOnly:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'1',trim:'1'),lang:pascal,libs:!(),options:'-O3+-Ci-+-Cr-+-g-+-CX+-XXs',source:1),l:'5',n:'0',o:'x86-64+fpc+3.0.4+(Editor+%231,+Compiler+%231)+Pascal',t:'0')),k:42.8345650377193,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compiler:1,editor:1,wrap:'1'),l:'5',n:'0',o:'%231+with+x86-64+fpc+3.0.4',t:'0')),k:1.3387683965766675,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4>
As far as I've ever been able to surmise, the general problem is more that people continue to think they can pass records by value and have the compiler optimize the access for them, which it just simply doesn't.
As an side since you’re talking about optimizations what would it take to make the copy/addref record operators be inline? Unless I’m mistaken that’s one of the bigger issues that makes custom ref counted objects slower than built in compiler types. Just curious...
Regards,
Ryan Joseph
Ryan Joseph wroteAs an side since you’re talking about optimizations what would it take to make the copy/addref record operators be inline? Unless I’m mistaken that’s one of the bigger issues that makes custom ref counted objects slower than built in compiler types. Just curious...
That is something that is currently simply not possible.
Regards,
Sven
In the meantime, I have some optimisations that I would be grateful could be evaluated - two of them are specific to the compiler, but one is much more general-purpose, relating to case blocks.
https://bugs.freepascal.org/view.php?id=34859
https://bugs.freepascal.org/view.php?id=35346
https://bugs.freepascal.org/view.php?id=35433
Gareth aka. Kit
---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
As an side since you’re talking about optimizations what would it take to make the…
As an side since you’re talking about optimizations what would it take to make the copy/addref record operators be inline? Unless I’m mistaken that’s one of the bigger issues that makes custom ref counted objects slower than built in compiler types. Just curious...
I believe counter's atomicity there is a much more heavyweight factor.
---
Best regards, George
George Bakhtadze schrieb am Fr., 28. Juni 2019,
08:26:
This assumption is *not* incorrect. Only on the LLVM based Delphi NewGen and FPC's LLVM backend the assumption is incorrect which can be seen by them having added "volatile" mechanisms.
Regards,
Sven
George Bakhtadze schrieb am Sa., 29. Juni 2019,
09:32:
It does not guarantee atomicity and it's not mentioned in the documentation, but the non-LLVM backends *always* reaccess global variables
- and there is enough code out there, both FPC and Delphi/TP that (ab)use this so that it can be considered pseudo documented.
Regards,
Sven
It is not true, if possible, FPC puts global variables into registers.
Florian Klaempfl schrieb am Sa., 29. Juni 2019,
15:52:
Okay, then I stand corrected. 🤷♀️
Regards,
Sven
Hi,
George Bakhtadze wroteIf FPC somehow guarantees that a global field (even only of simple types) can be atomically read and written from any thread for ANY platform that is a very strong guarantee and worth mention in documentation.
btw, how would you do that if it is in not guaranteed? especially on arm
Are there functions to do only an atomic reads and writes? (besides functions like interlockedincrement that do both, a read and write, together)
Best,
Benito
btw, how would you do that if it is in not guaranteed? especially on arm Are there…
Really, insofar as x86 is concerned, the only ones that are guaranteed to be atomic are, I think, the ordinal types, but that still leaves problems of code such as the following:
if GlobalCounter = 10 then
begin
DoSomething;
Break;
end else
Inc(GlobalCounter);If two threads are running a loop with the following code at the end, it could be that GlobalCounter is 9, the condition is checked, but before Inc(GlobalCounter) is called, the scheduler switches to the other thread, where GlobalCounter is checked and is still 9, and is then incremented, and only then does it switch back to the other thread, where Inc(GlobalCounter) is finally called, thereby setting GlobalCounter to 11 and breaking the program.
In this instance, a critical section or some other mutex is required, or the interlocked instructions, all of which incur a performance penalty.
Definitely something for a lot of discussion!
Gareth aka. Kit
---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Op 2019-06-27 om 15:12 schreef George Bakhtadze:
Volatile (I assume you mean a C-like volatile) is usable in very rare special cases. Such as work with hardware buffers.
(in embedded targets it is not that rare. E.g. variables/state shared between interrupts handlers and main program)