Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2019-06

"Maybe Gareth can be convinced to spend his energy on this ... "

21 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton
to Michael Van Canneyt

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

Michael Van Canneyt wrote 24 lines
On Thu, 27 Jun 2019, J. Gareth Moreton wrote: > https://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. _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

Benito van der Zander
to J. Gareth Moreton: 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

J. Gareth Moreton wrote 14 lines
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 _______________________________________________ fpc-devel maillist  - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

J. Gareth Moreton
to Benito van der Zander

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

Benito van der Zander wrote 41 lines
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 Am 27.06.19 um 09:27 schrieb J. Gareth Moreton: > 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 > > _______________________________________________ > fpc-devel maillist  - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Sven Barth
to J. Gareth Moreton

J. Gareth Moreton schrieb am Do., 27. Juni
2019, 12:18:

Show quoted text 5 lines
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.

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

Reply by email

Ben Grasset
to Sven Barth: 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 <

Show quoted text 6 lines
wrote: 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.

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.

Reply by email

Ryan Joseph
to Ben Grasset

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

Reply by email

Sven Barth
to Ryan Joseph
Ryan Joseph wrote
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...

That is something that is currently simply not possible.

Regards,
Sven

Reply by email

J. Gareth Moreton
to Sven Barth

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

Reply by email

George Bakhtadze
to Ryan Joseph: 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

Reply by email

Sven Barth
to George Bakhtadze:

George Bakhtadze schrieb am Fr., 28. Juni 2019,
08:26:

Show quoted text 8 lines
Hello, > One thing I have been considering is to promote fields and global variables to local registers to reduce memory accesses. That would be great. But multithreaded code which assume (incorrectly) that those fields and globals are in memory may be broken.

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

Reply by email

Sven Barth
to George Bakhtadze

George Bakhtadze schrieb am Sa., 29. Juni 2019,
09:32:

Show quoted text 13 lines
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. I believe this assumption incorrect because it's not stated in documentation as correct. If 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.

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

Reply by email

Florian Klaempfl
to George Bakhtadze:
George Bakhtadze wrote 6 lines
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. I believe this assumption incorrect because it's not stated in documentation as correct.

It is not true, if possible, FPC puts global variables into registers.

Reply by email

Sven Barth
to Florian Klaempfl

Florian Klaempfl schrieb am Sa., 29. Juni 2019,
15:52:

Show quoted text 10 lines
Am 28.06.2019 um 11:24 schrieb George Bakhtadze: > 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. > > I believe this assumption incorrect because it's not stated in > documentation as correct. It is not true, if possible, FPC puts global variables into registers.

Okay, then I stand corrected. 🤷‍♀️

Regards,
Sven

Reply by email

Benito van der Zander
to George Bakhtadze:

Hi,

George Bakhtadze wrote
If 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

Reply by email

J. Gareth Moreton
to Benito van der Zander:  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

Benito van der Zander wrote 20 lines
Hi, Am 28.06.19 um 11:24 schrieb George Bakhtadze: > If 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 _______________________________________________ fpc-devel maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

---
This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Reply by email

Marco van de Voort
to George Bakhtadze:

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)

Reply by email