Try   HackMD

c language: volatile and optimization 影響效能的關鍵之一

tags: C LANGUAGE linux volatile

Author: WhoAmI
email: kccddb@gmail.com

Date: 20220726
Copyright: CC BY-NC-SA

因為為了讀者方便實際實驗, 因此使用 cygwin 並使用 gcc -Os 實驗 volatile (GCC optimal compile flags) gcc 還有許多優化例如浮點運算, 多媒體, 省電等與 CPU 有關的參數可以加速多媒體方面的應用!建議有需要的讀者詳細研讀使用的 SoC 或 CPU datasheet. 有些單晶片優化後不能用, 有些與 volatile 有關

volatile 也常與 I/O 很大關係!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

另一是 programmer 統計學的概念 (HINT: Principle of locality)

if (發生機率 高的條件) {

}else {

}
通常效能較好.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

寫了一個簡單的x86程式
loop.c
測試
volatile and optimization

gcc -DTEST -Os loop.c -o loop
gcc -DTEST loop.c -o loop
or
gcc -Os loop.c -o loop
gcc loop.c -o loop

另外還有 -O2 與 -O3 等

$ gcc help

-S
-shared
-static
-Wall
-shared -fPIC (Position-Independent Code) 詳細看您的 gcc 這主要產生 .so shared library

用 Ctrl C 測試 4 種結果
如需終止 process (執行中的程式) 可用 kill <pid>. pid 請看 printf 的輸出

/* volatile and optimization Author: WhoAmI 2018 */ #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> /* gcc -DTEST -Os loop.c -o loop gcc -DTEST loop.c -o loop or gcc -Os loop.c -o loop gcc loop.c -o loop */ static int value=0; #ifdef TEST static volatile int *P0; #else static int *P0; #endif static void signal_handler ( int signum){ switch (signum){ case SIGPIPE: fprintf(stderr,"Broken pipe!\n"); perror("SIGPIPE"); break; case SIGINT: fprintf(stderr,"Interrupt(SIGINT errno= %d)! PID=%d\n",errno,getpid()); *P0=1; break; case SIGALRM: fprintf(stderr,"Interrupt(SIGALRM errno= %d)!\n",errno); break; default: break; } } void loop (void) { *P0=0; while (*P0 != 1); printf("Quit!\n"); } int main(){ pid_t pid; P0=&value; pid=getpid(); printf("Press <Ctrl C> (send SIGINT signal)\n"); printf("PID(process ID) is %d.\nYou can use \n\nkill %d\n\nterminate this process from another terminal.\n",pid,pid); signal(SIGINT,signal_handler); loop(); }

** 注意 4 種結果 **
這 loop 很耗CPU 資源, 不是恰當的做法

​​​​laikc@laikc-PC ~

$ gcc -DTEST -Os loop.c -o loop

laikc@laikc-PC ~
$ ./loop
Press <Ctrl C> (send SIGINT signal)
PID(process ID) is 2676.
You can use

kill 2676

terminate this process from another terminal.
Interrupt(SIGINT errno= 0)! PID=2676
Quit!

laikc@laikc-PC ~
$


laikc@laikc-PC ~
$ gcc -DTEST loop.c -o loop
laikc@laikc-PC ~
$ ./loop
Press <Ctrl C> (send SIGINT signal)
PID(process ID) is 1748.
You can use
kill 1748
terminate this process from another terminal.
Interrupt(SIGINT errno= 0)! PID=1748
Quit!
laikc@laikc-PC ~


laikc@laikc-PC ~
$ gcc -Os loop.c -o loop
laikc@laikc-PC ~
$ ./loop
Press <Ctrl C> (send SIGINT signal)
PID(process ID) is 3724.
You can use
kill 3724
terminate this process from another terminal.
Interrupt(SIGINT errno= 0)! PID=3724
Interrupt(SIGINT errno= 0)! PID=3724
Interrupt(SIGINT errno= 0)! PID=3724


laikc@laikc-PC ~
$ gcc loop.c -o loop
laikc@laikc-PC ~
$ ./loop
Press <Ctrl C> (send SIGINT signal)
PID(process ID) is 4572.
You can use
kill 4572
terminate this process from another terminal.
Interrupt(SIGINT errno= 0)! PID=4572
Quit!
laikc@laikc-PC ~
$