View Issue Details

IDProjectCategoryView StatusLast Update
0032721FPCCompilerpublic2017-11-27 14:43
ReporterkupferstecherAssigned To 
PrioritynormalSeverityminorReproducibilityN/A
Status newResolutionopen 
PlatformembeddedOSOS Version
Product VersionProduct Build 
Target VersionFixed in Version 
Summary0032721: [FEATURE REQUEST] Implicit 'volatile' for globals
DescriptionCurrently there seems to be no concept to define 'volatile' variables, i.e. that these variables are never optimised but loaded and stored to memory once for each occurance in the code. For target embedded this is an essential feature (Interrupts etc.). There is no neccessity to introduce a variable modifier, but the volatility may also be defined implicitly, e.g. for all global variables. While there are hints that this (implicit volatile for globals) is the common way in the pascal languages and the fpc compiler actually does less optimisation on globals, some easy tests showed that there are still optimisations performed and a 'non-optimistaion' seems not to be in the documentation.

So my suggestion (feature request) is
- to treat globals always as non-optimisable variables
 OR
- to define a variable modifier 'volatile' that can be applied to any variable

Thread on the forum (2017):
http://forum.lazarus.freepascal.org/index.php?topic=38961

Mailinglist (2015):
http://lists.freepascal.org/pipermail/fpc-pascal/2015-December/046055.html
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Thaddy de Koning

2017-11-23 12:17

reporter   ~0104224

Last edited: 2017-11-23 12:21

View 3 revisions

"Volatile" as in the C language means a "constant" stored at a fixed memory allocation for which its value can not be assumed to be constant. As opposed to a constant that can be resolved at compile time by the compiler.
Some flavors of the Pascal language have that concept as "Assignable typed constant" including FPC.
I suggest no change required.

Thaddy de Koning

2017-11-23 12:24

reporter   ~0104225

Last edited: 2017-11-23 12:29

View 4 revisions

Also note that an assignable typed constant is even more flexible.....
I tried but I - obviously - failed in that discussion but here's the theory behind it:
https://en.wikipedia.org/wiki/Volatile_(computer_programming)

"In computer programming, particularly in the C, C++, C#, and Java programming languages, the volatile keyword indicates that a value may change between different accesses, even if it does not appear to be modified. This keyword prevents an optimizing compiler from optimizing away subsequent reads or writes and thus incorrectly reusing a stale value or omitting writes. Volatile values primarily arise in hardware access (memory-mapped I/O), where reading from or writing to memory is used to communicate with peripheral devices, and in threading, where a different thread may have modified a value."

Thaddy de Koning

2017-11-23 12:34

reporter   ~0104226

Last edited: 2017-11-23 12:36

View 2 revisions

Note that the latter part of that quote is application, NOT design. That may confuse the careful reader....
It boils down to a value at a fixed memory address... nothing more, nothing less...

Martok

2017-11-23 17:27

reporter   ~0104232

Thaddy, you are wrong. As has been pointed out to you in the forum thread, {$J+} can mimic the "static" modifier. "volatile" is something different and defines the single access pattern the compiler is allowed to generate.


On Topic: 'absolute' has been suggested but also does not help.

The implication is that common embedded code will likely not work as expected:
  while (PORTB and 1)=0 do ; // wait for PORTB0 to become set
That might get optimized to one load to an R register, and multiple branches based on that (now wrong) register value.

Bitpacked arrays appear to be implicitly volatile, even when copied in full. So the above example could be rewritten as:
  _PORTB = bitpacked array[0..7] of boolean absolute PORTA;
  while not _PORTB[0]=0 do ; // wait for PORTB0 to become set
Of course, that is completely useless for anything that is conceptually not a bitfield.

Christo Crause

2017-11-24 09:05

reporter   ~0104236

I am a fan of unambiguous keywords/modifiers/descriptors. So if one starts with the assumption that the meaning of programming constructs are related to their typical English meaning then the Pascal keyword const in my mind is related to the English meaning of constant. Here I want to refer to the Oxford dictionary definition 1.1 - Remaining the same over a period of time. This in my mind can be translated into the compiler assuming that a value listed as const doesn't have to be read multiple times because the value is not supposed to change.

It therefore seems counter intuitive (to me as non-native English speaker) that the compiler should assume the opposite, i.e. that a value should be read on every access in case it was somehow changed.

I know this is going off on a tangent, but the whole concept of runtime assignable const seems insane. I know there is a compatibility argument behind this, but it leads to constructs such as Thaddy's assertion in the first comment.

jamie philbrook

2017-11-24 22:47

reporter   ~0104245

here we go again...

 Volatile means only one thing in the C language and it has nothing to do with
fixed memory..

 The idea is to inform the compiler that such a variable without notice and without change of any code locally taking place could change its value(content).

 This can cause issues in several cases where for example, an Interrupt handler
could be changing a value and the compiled code needs to know this so that
proper code is used for optimization.

 Lets step back and use a secondary thread as an example which can also generate
the same results as a hardware interrupt changing values.

 When marking a variable VOLATILE, it can inform the compiler that it needs to
always reference the original source each time code makes a reference to it. This is needed to keep a constant Real time update of the value sitting there.
 
 for example, lets say I read a specific variable that is getting access in another thread and you have your current block of code performing a loop checking for this value.. You don't want it to load the value into a Register or
some other temp storage holder to make the current block of code more efficient.

 Also on another note, In cases like a CASE statement where you first gets the
Case index to search the list, you don't want it to be reloading the index value each time from the original source if its marked as Volatile..

 This is nothing more than an optimizer for the compiler and most likely needed
in cases for short code blocks where a compiler will see a change to optimize the operation by loading the value into a register where it gets referenced but not changed several times in the block of code. that will fail if this value is being changed elsewhere in the background.

Thaddy de Koning

2017-11-25 10:44

reporter   ~0104249

Last edited: 2017-11-25 10:45

View 2 revisions

Jamie and Martok read your curriculum again... Volatile can be reduced to what I - and wikipedia - (and that entry was not written by me) wrote. You can also look up the specs for C. Or for beginners read this, which is also correct.:
https://www.embedded.com/electronics-blogs/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword

In Pascal you can use an assignable typed const. It is the same.

It is hiding in plain sight... too simple?

Florian

2017-11-25 20:25

administrator   ~0104265

The statement of Jonas is still valid. So is there any usefull(!) example code where FPC shows a behaviour which is not solvable without volatile?

> On Topic: 'absolute' has been suggested but also does not help.

Why not (besides the fact that it might not be documented)?

jamie philbrook

2017-11-25 21:16

reporter   ~0104267

I am sorry, I don't need to read about this subject, I was doing C with
micro controls years ago and under stand fully what VOLATITE does is all
about is.
  
 if I ever need to write code for such a case I'll most likely do inline
ASM or move the project to another compiler that understands it.

 I'll say no more since it's obvious where this is going..

 It was an interested discussion to say the least and it has tough me
a few things software politics

kupferstecher

2017-11-26 11:59

reporter   ~0104278

@Florian: I came up with the topic in order to get more then a vague feeling on how the optimisation internally works. The AVR-Embedded and ARM-Embedded ports are still quite buggy, so one can not just trust that an error always comes from the user code. Therefore the behaviour has to be clearly defined (documentation).

> So is there any usefull(!) example code where FPC shows a behaviour which is not solvable without volatile?
Firstly the behaviour has to be guaranteed, its not enough if its just showed behaviour.
The volatile behaviour for 'absolute' variables is essential for the register definitions.
But for user variables used in interrupts non-absolute variables also need to be volatile. If globals do provide that, its enough.
If I understood Jonas correctly, then globals actually do provide that. But thats also not documented behaviour and the i386-compiler seems not to completely follow that rule.

Also I beliefe that volatile behaviour in some extent is already and always used in threading desktop applications. E.g. instance variables are not optimised out of loops, while for a non-volatile variable it would be useless to poll an unchanged variable in a loop. Example (typical in TThread.Execute):
 while not Terminated do...
In short: There obviously already is a concept of volatility.

Besides the technical aspects I think for the language itself this is a very important topic. It took me a long time to understand that locals are better optimised. In the beginning I thought that there is no 'real' optimisation possible if there is no volatile keyword, which gave me a negative impression of freepascal. This doesn't mean that because of this a volatile modifier is needed, but the behaviour has to be clear to everyone. And as the forum discussion showed, and also the discussion now, there is nearly nobody to really understand the current optimisation concept in regards to variables.

Regards

Maciej Izak

2017-11-27 08:44

reporter   ~0104305

@Florian: probably is worth to mention example: http://forum.lazarus.freepascal.org/index.php/topic,38961.msg267011.html#msg267011

interesting topic :)

Martok

2017-11-27 14:43

reporter   ~0104308

>> On Topic: 'absolute' has been suggested but also does not help.
> Why not (besides the fact that it might not be documented)?

Codegen is the exactly same as for a "normal" variable, seemingly redundant loads get optimized out.

Issue History

Date Modified Username Field Change
2017-11-23 12:01 kupferstecher New Issue
2017-11-23 12:17 Thaddy de Koning Note Added: 0104224
2017-11-23 12:19 Thaddy de Koning Note Edited: 0104224 View Revisions
2017-11-23 12:21 Thaddy de Koning Note Edited: 0104224 View Revisions
2017-11-23 12:24 Thaddy de Koning Note Added: 0104225
2017-11-23 12:26 Thaddy de Koning Note Edited: 0104225 View Revisions
2017-11-23 12:27 Thaddy de Koning Note Edited: 0104225 View Revisions
2017-11-23 12:29 Thaddy de Koning Note Edited: 0104225 View Revisions
2017-11-23 12:34 Thaddy de Koning Note Added: 0104226
2017-11-23 12:36 Thaddy de Koning Note Edited: 0104226 View Revisions
2017-11-23 17:27 Martok Note Added: 0104232
2017-11-24 09:05 Christo Crause Note Added: 0104236
2017-11-24 22:47 jamie philbrook Note Added: 0104245
2017-11-25 10:44 Thaddy de Koning Note Added: 0104249
2017-11-25 10:45 Thaddy de Koning Note Edited: 0104249 View Revisions
2017-11-25 20:25 Florian Note Added: 0104265
2017-11-25 21:16 jamie philbrook Note Added: 0104267
2017-11-26 11:59 kupferstecher Note Added: 0104278
2017-11-27 08:44 Maciej Izak Note Added: 0104305
2017-11-27 14:43 Martok Note Added: 0104308