[Info-vax] LLVM, volatile and async VMS I/O and system calls

Jan-Erik Söderholm jan-erik.soderholm at telia.com
Sun Oct 3 14:53:23 EDT 2021


Den 2021-10-03 kl. 17:47, skrev chris:
> On 10/03/21 15:21, Bill Gunshannon wrote:
>> On 10/3/21 8:29 AM, chris wrote:
>>> On 10/03/21 10:21, Jan-Erik Söderholm wrote:
>>>> Den 2021-10-03 kl. 01:06, skrev chris:
>>>>>
>>>>> So, it really comes down to optimiser choice of instruction, depending
>>>>> on the use of the volatile keyword. Perhaps optimisers might optimise
>>>>> such reads out, but that common ?.
>>>>
>>>> Optimizing out code not needed is one of the most common things that
>>>> optimizers does. A very short example.
>>>>
>>>> int a;
>>>> int b;
>>>> void main() {
>>>> a = 10;
>>>> b = a;
>>>> b = a;
>>>> }
>>>>
>>>> The second assignment to b will simply be removed since it is
>>>> a duplicate of the first and the value of a has not changed, at
>>>> least not as far as the compiler can see.
>>>>
>>>> Compare with:
>>>>
>>>> int volatile a;
>>>> int b;
>>>> void main() {
>>>> a = 10;
>>>> b = a;
>>>> b = a;
>>>> }
>>>>
>>>> This tells the compiler that the value of a can change outside of
>>>> the current compile unit and both assignments will be left to be
>>>> done and the value of b could be different after each assignment.
>>>>
>>>> The first generates 7 Alpha instructions and the second 9 instructions.
>>>
>>> Would be interesting to see instructions generated, so we can see what
>>> is happening. Instruction count alone doesn't say much.
>>
>> More interesting than you might thnk. Here's an x86 version.
>>
>> .text
>> .globl main
>> .type main, @function
>> main:
>> .LFB0:
>> .cfi_startproc
>> movl $10, a(%rip)
>> movl $10, b(%rip)
>> ret
> 
> Years since X86 asm and it's more complicated now, since there is
> Intel asm format for windows and AT&T format for Linux, so assume this is 
> AT&T <inst> <src> <dest> format.
> 
> So 10 copied to a and b, rather than first to a, then b from a, as
> per source. Second copy optimised out, as expected.
>>
>> .text
>> .globl main
>> .type main, @function
>> main:
>> .LFB0:
>> .cfi_startproc
>> movl $10, a(%rip)
>> movl a(%rip), %eax
>> movl a(%rip), %eax
>> movl %eax, b(%rip)
>> ret
>> .cfi_endproc
> 
> So in this case, gone round the houses a bit more, using
> an intermediate  register, but faithfully retained the
> redundant second copy.

Well, the whole point of this discussion is that the second
copy is *NOT* redundant. Adding "volatile" makes that clear.

The value of a *could* have changed between the two reads.
That is exactly what "volatile" is all about.

> 
> One of the points I was trying make earlier was that code
> should never depend on optimisation level,...

If you add "volatile" where it is needed, you do not need to
depend on any optimisation level. And one "volitile" too
much is usually better then one to little.

> and for app
> code, there are better high level methods for
> controlling shared access, such as signals or callbacks
> to encapsulate an async process.

If a had been pointing to some hardware register, that is
updated by the hardware and not by other code, no signals,
callbacks or any other coding technique can change that.
*The* way (in C) is to add "volatile" to the varaible.

It has nothing to do with coding style or such, only with
proper understanding of the context the code is running in.

> 
> Good tech discussion this though :-)...
> 
> Chris
> 
> 
> 
> 
>>
>> Most interesting.
>>
>> bill
> 




More information about the Info-vax mailing list