# 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 很大關係!**

另一是 programmer 統計學的概念 (HINT: **Principle of locality**)
if (發生機率 高的條件) {
}else {
}
通常效能較好.

寫了一個簡單的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 ~
$
---