Author Topic: Disabling Compiler Optimization vs Using volatile  (Read 28639 times)

0 Members and 7 Guests are viewing this topic.

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Disabling Compiler Optimization vs Using volatile
« Reply #150 on: July 13, 2025, 02:19:51 pm »
My usual technique..

1) Capture raw input in an ISR, put the raw info into a FIFO, return from interrupt.

2) task reads FIFO, and converts raw input into a standard internal event, processes that in an FSM, outputs any appropriate actions, possibly puts new event in FIFO, possibly my pokes hardware. Frequently use the half-sync half-asynch design pattern.

3) logging is largely keeping a very compact representation of events and states and actions. Brevity means it can be enabled during normal operation. Very convenient for field and remote maintenance.

4) performance can be monitored by observing FIFO queue size.It

5) log also convenient when arguing with other companies about who is responsible for fault found during system integration.

Single stepping is used when checking  event creation and actions poking hardware, but is rarely used otherwise: the log is better.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Disabling Compiler Optimization vs Using volatile
« Reply #151 on: August 06, 2025, 08:26:16 am »
Just came across this while reorganising my bookmarks...

Nine ways to break your systems code using volatile
http://blog.regehr.org/archives/28
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: macboy, Siwastaja

Offline macboy

  • Super Contributor
  • ***
  • Posts: 2412
  • Country: ca
Re: Disabling Compiler Optimization vs Using volatile
« Reply #152 on: August 09, 2025, 02:38:45 pm »
Just came across this while reorganising my bookmarks...

Nine ways to break your systems code using volatile
http://blog.regehr.org/archives/28
And his #1 way to break your system using volatile is ... "Not enough volatile". In other words, not using it when it really should be used.

That is a great read, written by someone who seems to know a fair bit about the C standards and compilers, and who has a good amount of experience writing systems/kernel/driver code. Thanks for the link!
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4852
  • Country: us
Re: Disabling Compiler Optimization vs Using volatile
« Reply #153 on: August 09, 2025, 03:22:42 pm »
It's a good read but you have to keep in mind when it was written (2010) and what platform it mostly addresses (avr-gcc).

C11 introduced atomics, and by now most 32 but microcontrollers can support them.  Several of the listed ways to break your code should probably be updated to "use atomics if available" instead of using inline assembly to create memory barriers.

Also most arm platforms have vendor provided headers that supply all the register definitions correctly marked volatile.  If you can use those it will exclude 90% of problem #1 "not enough volatile"
« Last Edit: August 09, 2025, 03:34:18 pm by ejeffrey »
 
The following users thanked this post: macboy

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Disabling Compiler Optimization vs Using volatile
« Reply #154 on: August 09, 2025, 03:35:02 pm »
My attitudes...

Most people who think they understand C's volatile, don't. (EDIT: a brain fart caused me to originally write "atomic".)

Junk DNA in languages is a fertile source of subtle late surprises.

Why doesn't anybody think of the children people maintaining projects written in C89, C99,... :)
« Last Edit: August 09, 2025, 04:14:12 pm by tggzzz »
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4852
  • Country: us
Re: Disabling Compiler Optimization vs Using volatile
« Reply #155 on: August 09, 2025, 04:04:19 pm »
There are definitely plenty of pitfalls with atomics.  C/C++ also definitely give you all the tools you need to get into trouble with e.g., relaxed atomics.  And you can't really use them without knowing what types are lock free on your platform.

For complex data structures outside an interrupt handler, locks remain the easiest and often best approach.

But for simple uses like an atomic flag they mostly work. They are also pretty easy to use to implement locks if you aren't happy with your platform provided locks.

On the other hand atomics solve a lot of the problems with people trying to abuse volatile for concurrency because they actually implement both a compiler and a memory barrier. Volatile access provides neither.  Also while their primary purpose is for inter thread communication they can actually be used for IO registers in many cases.  This is especially the useful if you are doing DMA, where atomics are absolutely the best way to ensure that the memory buffers stay coherent with the dma head/tail pointers.

Yes they can be dangerous but not as dangerous as using the wrong tool for the job.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Disabling Compiler Optimization vs Using volatile
« Reply #156 on: August 09, 2025, 04:13:27 pm »
There are definitely plenty of pitfalls with atomics.  C/C++ also definitely give you all the tools you need to get into trouble with e.g., relaxed atomics.  And you can't really use them without knowing what types are lock free on your platform.

For complex data structures outside an interrupt handler, locks remain the easiest and often best approach.

But for simple uses like an atomic flag they mostly work. They are also pretty easy to use to implement locks if you aren't happy with your platform provided locks.

On the other hand atomics solve a lot of the problems with people trying to abuse volatile for concurrency because they actually implement both a compiler and a memory barrier. Volatile access provides neither.  Also while their primary purpose is for inter thread communication they can actually be used for IO registers in many cases.  This is especially the useful if you are doing DMA, where atomics are absolutely the best way to ensure that the memory buffers stay coherent with the dma head/tail pointers.

Yes they can be dangerous but not as dangerous as using the wrong tool for the job.

I've corrected my brain fart where I meant "volatile" but wrote "atomic".It

Apologies
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online gf

  • Super Contributor
  • ***
  • Posts: 1833
  • Country: de
Re: Disabling Compiler Optimization vs Using volatile
« Reply #157 on: August 10, 2025, 12:43:22 pm »
There are definitely plenty of pitfalls with atomics.  C/C++ also definitely give you all the tools you need to get into trouble with e.g., relaxed atomics.

But even 'relaxed' has its justification sometimes.

Quote
And you can't really use them without knowing what types are lock free on your platform.

You can, however, test if a particular atomic type is lock-free, using atomic_is_lock_free() and the ATOMIC_XXX_LOCK_FREE macros in C. In C++ there is also std::atomic<T>::is_always_lock_free, which is constexpr.

In C or C++, the primary meaning of 'atomic' is 'atomic with regard to other threads'. This does not require lock-freeness, but it can be achieved with locks as well.

A different (or additional) aspect is asynchronous signal safety, and it is only guaranteed for lock-free atomic data types; in other words, only lock-free atomic data types can be safely manipulated in signal or interrupt handlers.

Quote
But for simple uses like an atomic flag they mostly work.

In fact, atomic_flag is the only atomic type which is always guaranteed to be lock-free (on every platform that supports stdatomic).
« Last Edit: August 10, 2025, 07:50:14 pm by gf »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->