Andrew is right.

Volatile makes compiler read variable value from memory each time. Reading from 
memory does not mean that it will skip the cache. It still could get the value 
from the cache if cache is enabled and valid.  Volatile and cache are different 
stores.

Thanks!
Jeff
From: Andrew Fish [mailto:af...@apple.com]
Sent: Thursday, March 05, 2015 10:31 AM
To: edk2-devel@lists.sourceforge.net
Cc: Fan, Jeff
Subject: Re: [edk2] [v2 4/4] UefiCpuPkg/MpSerivce: remove volatile qualifier


On Mar 4, 2015, at 5:34 PM, Chen Fan 
<chen.fan.f...@cn.fujitsu.com<mailto:chen.fan.f...@cn.fujitsu.com>> wrote:

Hi Jeff,

Thanks for your explanation, I didn't encounter any issue if leaving it
there.

I just think if use Volatile qualifier may cause the problem of
performance. because
access the value need to copy the address value  from main memory to cpu
cache
each time and not use the cache.
and IIRC, in a shared memory multiprocessor system, the cache coherence may
keep the consistency of shared resource data in each processor local
caches.
if the value is updated by one processor in local cache, the copy of
memory data in
other processor caches will be marked as invalid. and then other
processors read the
value will access from the main memory.
if I misunderstand, please correct me. :)

Correction!

Volatile in C has nothing to do with hardware and caching. It has to do with 
the abstract memory model for the compiler as defined by the C standard. The 
more aggressive the compiler optimizes the code the more you are exposed to 
potential issues. If the compiler knows about all the code in the program that 
accesses a variable it can assume that memory location will only be changed by 
the compiler, and make optimizations (like storing a pointer in a register).

A common optimization is to avoid memory reads that are not needed. Here is a 
simple example in clang, probably the most aggressive optimizing compiler I 
know of…. (My comments start with #):

~/work/Compiler>cat volatile.c
int
main (int argc, char **argv)
{
  int *i = (int *)0xFFFFFFF0;

  while (*i != 0);
  return 0;
}
~/work/Compiler>clang volatile.c -S -O3
~/work/Compiler>cat volatile.S
                .section    __TEXT,__text,regular,pure_instructions
                .globl       _main
                .align        4, 0x90
_main:                                  ## @main
                pushq      %rbp
                movq       %rsp, %rbp
                movl        $4294967280, %eax       ## imm = 0xFFFFFFF0
                cmpl        $0, (%rax)
                je             LBB0_2
#  Notice the compiler only does a single read. The memory model of C implies 
this memory will not change.

                .align        4, 0x90
LBB0_1:                                 ## %..split_crit_edge
                                        ## =>This Inner Loop Header: Depth=1
                jmp          LBB0_1
# Notice this while loop is just an infinite loop? There is no point reading 
the memory since the C spec states it will not change.

LBB0_2:                                 ## %.split1
                xorl          %eax, %eax
                popq        %rbp
                retq

If I make i a volatile variable it forces the compiler to read it every time: 
volatile int *i = (int *)0xFFFFFFF0;

~/work/Compiler>cat volatile.S
                .section    __TEXT,__text,regular,pure_instructions
                .globl       _main
                .align        4, 0x90
_main:                                  ## @main
                pushq      %rbp
                movq       %rsp, %rbp
                movl        $4294967280, %eax       ## imm = 0xFFFFFFF0
                .align        4, 0x90
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
                cmpl        $0, (%rax)
                jne           LBB0_1
# Now it reads every iteration of the while loop

                xorl          %eax, %eax
                popq        %rbp
                retq

So the point of making it volatile is to force the compiler to read the value 
every time the C code asks for the value.

Thanks,

Andrew Fish


Thanks,
Chen



On 03/04/2015 03:56 PM, Fan, Jeff wrote:

Chen,

Volatile is to tell compiler this variable maybe changed by other threads.  
Compiler must access the value from memory instead of the old value in its 
registers.   This is different with spinlock that is to protect shared memory 
between multiple threads.

For this case, CpuState may be updated by BSP/AP. I prefer to keep volatile 
type. Do you meet any issue if keepping this type?

Besides it, I also suggest to add volatile for the following variable.
CpuData->Parameter
CpuData->Procedure

Thanks!
Jeff

-----Original Message-----
From: Chen Fan [mailto:chen.fan.f...@cn.fujitsu.com]
Sent: Tuesday, March 03, 2015 1:06 PM
To: edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
Cc: Fan, Jeff; Justen, Jordan L
Subject: [v2 4/4] UefiCpuPkg/MpSerivce: remove volatile qualifier

because manipulating CpuState always with lock protection. so volatile 
qualifier is redundant.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chen Fan 
<chen.fan.f...@cn.fujitsu.com<mailto:chen.fan.f...@cn.fujitsu.com>>
---
 UefiCpuPkg/CpuDxe/CpuMp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h index 
cb3460f..e54b571 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -92,7 +92,7 @@ typedef struct {
   EFI_PROCESSOR_INFORMATION      Info;
   SPIN_LOCK                      CpuDataLock;
   INTN                           LockSelf;
-  volatile CPU_STATE             State;
+  CPU_STATE                      State;

   EFI_AP_PROCEDURE               Procedure;
   VOID                           *Parameter;
--
1.9.3

.


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to