Recent

Author Topic: Statement as memory barrier for globals ("volatile")  (Read 16830 times)

kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Statement as memory barrier for globals ("volatile")
« on: November 15, 2017, 01:23:30 pm »
I found a discussion about why fpc doesn't need the volatile modifier for variables as it exists in C (Link below) and still is capable of doing optimisations.

My understanding is that global variables are loaded or stored for each statement they are used at least once (implicit "volatile" for globals). And on contrast local variables are free for any optimisations, also throughout several statements or may be even optimised away.

My question now is, which variables are 'global' and which are 'local' in the meaning of memory barriers?
A variable defined in the units interface section is global (of course).
A variable pointing to an absolute address is global (yes).
Is a public variable of a class or object 'global'?
Is a private variable of a class or object 'global'?
Is a class variable 'global'?
Is a variable defined in the implementation section 'global'?

So i want to know if there is anything to consider regarding optimisations when using interrupt handlers for example (target embedded).

Thanks!

I cite:
Quote
In FPC, every statement is basically considered to be a compiler-level
memory barrier for accesses to global variables. So within a single
statement multiple accesses can be optimised, but that cannot happen not
across statements. It's not perfect since it inhibits some optimisation,
but on the flip side it's very simple and easy to reason about.
[...]
The reason the need for volatile on embedded systems is far less in FPC,
is the existence of the "absolute" keyword. In C, you have to declare
all of those memory mapped registers as volatile pointers, because
otherwise things will get optimised wrongly. In FPC, you can declare
them as variables that are "absolute" at some address, and the compiler
will never optimise their accesses. Only if you would take the address
of one of these variables and store it in a pointer, you would need
"volatile" in this context.
http://lists.freepascal.org/pipermail/fpc-pascal/2015-December/046055.html

Thaddy

  • Hero Member
  • *****
  • Posts: 8521
Re: Statement as memory barrier for globals ("volatile")
« Reply #1 on: November 15, 2017, 04:08:38 pm »
Volatile (C and derivatives) is the same as a Pascal writeable typed const ({$J+/-}

It indicates a type of var (typed const) that needs an allocation instead of being optimized away to a fixed - const - value.
It has a memory allocation on the heap instead of on the stack. Pascal had that *before* C and derivatives.

Example:
Code: Pascal  [Select]
  1. program volatility;
  2. {$mode objfpc}
  3.  
  4. function ShowVolatile:integer;
  5. {$push}{$J+}
  6. const t:integer = 0; // this equals a C type volatile....
  7. {$pop}
  8. begin
  9.   Result := t;
  10.   inc(t); // almost always an atomic operation for the native register size
  11. end;
  12.  
  13. var i:integer;
  14. begin
  15.   for i := 0 to 9 do writeln(ShowVolatile);
  16. end.

Which also demonstrates that your informant was wrong: Pascal sometimes needs a "volatile" and the language provides it....

Note that on most - but not all - platforms this is atomic for the native register size or less... (And NO C isn't any better..... worse)
« Last Edit: November 15, 2017, 04:50:57 pm by Thaddy »
Read the manuals and if you are a professional get a proper education in computer science. Makes the forum a lot cleaner.

kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Re: Statement as memory barrier for globals ("volatile")
« Reply #2 on: November 15, 2017, 04:58:35 pm »
Thats interesting. Why seems that nobody knows that?
But how about the global variables, don't they provide the same?

Thaddy

  • Hero Member
  • *****
  • Posts: 8521
Re: Statement as memory barrier for globals ("volatile")
« Reply #3 on: November 15, 2017, 05:09:04 pm »
Thats interesting. Why seems that nobody knows that?
But how about the global variables, don't they provide the same?
Yes and no: global variables are global. Volatiles aren't. In the above example the volatile T is not accessible on a global level. Scoping.
C used to use simple globals but that is at the risk of unintentionally modifying it. Pascal also allows that, though.

And.... really old hands know.... 8-) All of'm...

Maybe wikipedia helps (again, pretty accurate):
https://en.wikipedia.org/wiki/Volatile_(computer_programming)

Even after the wiki it can be confusing: scoping tells it all: a volatile can be scoped, whereas a global can not.
« Last Edit: November 15, 2017, 05:31:08 pm by Thaddy »
Read the manuals and if you are a professional get a proper education in computer science. Makes the forum a lot cleaner.

kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Re: Statement as memory barrier for globals ("volatile")
« Reply #4 on: November 15, 2017, 09:14:59 pm »
Scoping is clear so far.

I did a little testing on target AVR:
Code: Pascal  [Select]
  1. while not IsSet do;
if IsSet is a local variable, then this will be kept as a register without address in the RAM, if its a field variable of an object, then it will be reloaded in each loop, even for the highest optimisation. For interrupt use this would normally be enough, but the question is if thats defined behaviour, or just a missing optimisation for that target.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Statement as memory barrier for globals ("volatile")
« Reply #5 on: November 15, 2017, 09:31:59 pm »
Volatile (C and derivatives) is the same as a Pascal writeable typed const ({$J+/-}

Sounds like you confused volatile with static.

Thaddy

  • Hero Member
  • *****
  • Posts: 8521
Re: Statement as memory barrier for globals ("volatile")
« Reply #6 on: November 15, 2017, 10:31:51 pm »
Volatile (C and derivatives) is the same as a Pascal writeable typed const ({$J+/-}

Sounds like you confused volatile with static.
No. C people have a different understanding of static. We have the correct one... It is as I explained.
As an afterthought, I put a wikipedia link for that reason. Read that. Or study computer science...
« Last Edit: November 15, 2017, 10:33:53 pm by Thaddy »
Read the manuals and if you are a professional get a proper education in computer science. Makes the forum a lot cleaner.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Statement as memory barrier for globals ("volatile")
« Reply #7 on: November 16, 2017, 03:33:47 am »
Volatile (C and derivatives) is the same as a Pascal writeable typed const ({$J+/-}

Sounds like you confused volatile with static.
No. C people have a different understanding of static. We have the correct one... It is as I explained.
As an afterthought, I put a wikipedia link for that reason. Read that. Or study computer science...
Thank you for the clarification and for the advice. I still think that your Pascal function ShowVolatile translates into C more or less like:
Code: C  [Select]
  1. int ShowVolatile()
  2. {
  3.     static int t = 0;
  4.  
  5.     return (t++);
  6. }

Where did I go wrong?

kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Re: Statement as memory barrier for globals ("volatile")
« Reply #8 on: November 17, 2017, 08:49:26 pm »
Thaddys example in my eyes also doesn't look like we are talking about the same topic, it seems to have nothing to do with optimisation.
The wiki-link on the other hand is about the topic I asked about.

Is there something in the documentation about that topic? I didn't find anything.

Regards

ASerge

  • Hero Member
  • *****
  • Posts: 1360
Re: Statement as memory barrier for globals ("volatile")
« Reply #9 on: November 17, 2017, 10:59:49 pm »
My understanding is that global variables are loaded or stored for each statement they are used at least once (implicit "volatile" for globals). And on contrast local variables are free for any optimisations, also throughout several statements or may be even optimised away.
My question now is, which variables are 'global' and which are 'local' in the meaning of memory barriers?
Variables inside functions or procedures are local. Global variables are defined outside function or procedure, those, the variables of the units and the body of the main program. Class or object fields are often called member variables. They behave as global, because they are available in different functions, but as local ones, because only used in the context of a class variable. This is the scope property.

Static is the lifetime of variable (until the end of the program). For example, all global variables. Or typed consts (local). Or class variables.

The absolute variable has the same properties as the variable that it refers to. Those, can be global, local, static, etc.

Volatile are variables in the C language that compiler must exclude from optimization, because their value can change outside the executed code. There is no corresponding directive in FPC. In C volatile can be static or not, global or local.

Global, local, member, static, absolute variables can be optimized by the compiler (now or in the future). To exclude a variable from optimization, replace it with a function call.

tetrastes

  • New Member
  • *
  • Posts: 33
Re: Statement as memory barrier for globals ("volatile")
« Reply #10 on: November 17, 2017, 11:35:15 pm »
Volatile (C and derivatives) is the same as a Pascal writeable typed const ({$J+/-}

Sounds like you confused volatile with static.
No. C people have a different understanding of static. We have the correct one... It is as I explained.
As an afterthought, I put a wikipedia link for that reason. Read that. Or study computer science...

So much clever words. This is translation of your example to C:
Code: C  [Select]
  1. #include <stdio.h>
  2.    
  3. int ShowVolatile(void)
  4. {
  5.     volatile int t = 0; // this IS a REAL C type volatile....
  6.     return t++;
  7. }
  8.  
  9. void main(void)
  10. {    
  11.     int i;
  12.    
  13.     for(i = 0; i < 10; i++) printf("%d\n", ShowVolatile());
  14. }
  15.  
  16.  

Compare the results. And then change volatile to static...

kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Re: Statement as memory barrier for globals ("volatile")
« Reply #11 on: November 18, 2017, 04:49:59 pm »
Global, local, member, static, absolute variables can be optimized by the compiler (now or in the future). To exclude a variable from optimization, replace it with a function call.
To use functions is quite ugly, there should be other methods. At least the globals with absolute adress have to work, otherwise the register definitions would be useless and registers only accessible through inline asm.

Sorry that I'm sceptical, but there are already contradicting statements now (Writable typed constants, globals, not possible at all...).

If there would be some reference, documentation...

jamie

  • Hero Member
  • *****
  • Posts: 1779
Re: Statement as memory barrier for globals ("volatile")
« Reply #12 on: November 19, 2017, 03:45:20 am »
Volatile is not really in the Pascal language however, if you properly code you can
come up with the same effect.

 Volatile simply tells the compiler that this "VARIABLE" could change without notice and there
for it should not be loaded in a Register for remaining code, the compiler should always reference
the variable from memory each time it needs to Read it and not optimize code to load its value into
a register for the remaining use of that variable in the current block.

 The best use for volatile variables is for things like Thread control, interrupt status changes etc.

 as for most Pascal generated code I think you'll notice it always reads from the original source.
 
 the only time it would only read once would be in a control loop, where as, changing the value in the
middle of a control loop would cause issues.

 As for the rest of it here.
 Writable constants are STATIC variables, defined at compile time and loaded as that value but
can be changed..
  They can be local to the procedure/function or global.

 Does that help?




kupferstecher

  • Sr. Member
  • ****
  • Posts: 289
Re: Statement as memory barrier for globals ("volatile")
« Reply #13 on: November 19, 2017, 09:51:52 am »
Volatile is not really in the Pascal language however, if you properly code you can
come up with the same effect.
Thanks for your post. I try to get the understanding how to do it correctly, as for target embedded this is elementary.

Quote
Volatile simply tells the compiler that this "VARIABLE" could change without notice and there
for it should not be loaded in a Register for remaining code, the compiler should always reference
the variable from memory each time it needs to Read it and not optimize code to load its value into
a register for the remaining use of that variable in the current block.
Yes, thats what I need.

Quote
Does that help?
Well thats a somehow a fourth opinion now, I should keep track, see below.

Volatiles are
- all writable typed constants
- all globals
- not possible at all
- variables that are not in loops

Btw I tested with writable typed constants (as local constant in a procedure) and for Target AVR they are reloaded in each loop cycle, while "standard" local vars are only kept in a register (Even doesn't have a physical address). Tested with -O4. But Target AVR doesn't optimise that much anyways, and there surely should be some documentation about such behaviour.

Does no one have a reference?

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: Statement as memory barrier for globals ("volatile")
« Reply #14 on: November 21, 2017, 03:26:13 am »
Does no one have a reference?

I don't think anyone has a reference because it does not exist.

What we can try to do is to test and prove the claims we see here. For instance, someone claimed that "volatile in Pascal is just a writable typed const". So we have to find one example where this claim does not seem to be true:
Code: Pascal  [Select]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Classes
  10.   { you can add units after this };
  11.  
  12. {$push}{$J+}
  13. const t:integer = 0;
  14. {$pop}
  15. var
  16.   i: integer;
  17. begin
  18.   t := 1;
  19.   i := t;
  20.   i := t;
  21.   i := t;
  22.   i := t;
  23.   i := t;
  24.   i := t;
  25.   i := t;
  26.   i := t;
  27.   i := t;
  28.   i := t;
  29. end.

The compiler (using -O3) emitted the following assembly:
Code: ASM  [Select]
  1. _main:
  2. # Var i located in register eax
  3. # [project3.lpr]
  4. # [18] begin
  5.         call    FPC_INITIALIZEUNITS
  6.         movl    $0,%eax
  7. # [19] t := 1;
  8.         movl    $1,TC_$P$PROJECT1_$$_T
  9. # Var i located in register eax
  10. # [20] i := t;
  11.         movl    $1,%eax
  12. # Var i located in register eax
  13. # [21] i := t;
  14.         movl    $1,%eax
  15. # Var i located in register eax
  16. # [22] i := t;
  17.         movl    $1,%eax
  18. # Var i located in register eax
  19. # [23] i := t;
  20.         movl    $1,%eax
  21. # Var i located in register eax
  22. # [24] i := t;
  23.         movl    $1,%eax
  24. # Var i located in register eax
  25. # [25] i := t;
  26.         movl    $1,%eax
  27. # Var i located in register eax
  28. # [26] i := t;
  29.         movl    $1,%eax
  30. # Var i located in register eax
  31. # [27] i := t;
  32.         movl    $1,%eax
  33. # Var i located in register eax
  34. # [28] i := t;
  35.         movl    $1,%eax
  36. # Var i located in register eax
  37. # [29] i := t;
  38.         movl    $1,%eax

Notice how i := t got optimized to movl $1,%eax

This refutes the claim that writable typed const in Pascal are equivalent to volatile variables in C.

@tetrastes Thanks for the C example.