# 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 很大關係!** ![](https://i.imgur.com/bSOTpU9.jpg) 另一是 programmer 統計學的概念 (HINT: **Principle of locality**) if (發生機率 高的條件) { }else { } 通常效能較好. ![](https://i.imgur.com/tAMm1Wu.jpg) 寫了一個簡單的x86程式 loop.c 測試 volatile and optimization :::info 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 的輸出 ```c= /* 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 ~ $ ---