# 羅習五 OSDI-hw7-詳解
###### tags: `LINUX_並發與競態_行程同步`
<style>
.blue {
color: blue;
}
.red {
color: red;
}
</style>
:::info
然後回答下列問題
1. 執行make,之後會產生四個執行檔案。請問你的執行節果為何?請附上畫面截圖
2. <span class="red">**「確實的」**</span> 解釋「為什麼」 peterson_trival-O3 的執行結果是錯的(問題二)
3. 請問在你的電腦上「peterson_trival-g」的速度比「 peterson_correct-O3」快或者是慢?上述二個程式的正確與否?
4. 請 <span class="red">**「確實的」**</span> 解釋「題三」,某個程式比另一個程式快或者慢的理由。
提示:『確實的』我建議**使用組合語言和計算機結構**來解釋
:::
系統環境

```
$ lscpu
架構: x86_64
CPU 作業模式: 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
每核心執行緒數: 1
每通訊端核心數: 2
Socket(s): 4
NUMA 節點: 1
供應商識別號: GenuineIntel
CPU 家族: 6
型號: 158
Model name: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
製程: 10
CPU MHz: 2208.001
BogoMIPS: 4416.00
Hypervisor 供應商: VMware
虛擬型態: 全部
L1d 快取: 32K
L1i 快取: 32K
L2 快取: 256K
L3 快取: 9216K
NUMA node0 CPU(s): 0-7
```
```
$ uname -a
Linux blue76815-virtual-machine 5.4.0-128-generic
#144~18.04.1-Ubuntu SMP Thu Sep 22 11:08:41 UTC
2022 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
```
## 1. 執行make,之後會產生四個執行檔案。請問你的執行節果為何?請附上畫面截圖
### case1:p0 和 p1 沒加 `nanosleep(&ts, NULL);`
peterson_trival.c 和 peterson_correct.c
把`//nanosleep(&ts, NULL);`註記掉
./peterson_trival-O3

./peterson_trival-g

./peterson_correct-O3

./peterson_correct-g

沒多久會進入
```
p0:p0及p1都在critical section
p1:p0及p1都在critical section
```

### case2:p0 和 p1 有加 `nanosleep(&ts, NULL);`
peterson_trival.c 和 peterson_correct.c
因為po p1加入 [nanosleep](https://man7.org/linux/man-pages/man2/nanosleep.2.html),因此執行緒**每次進出critical section有休眠**,造成切換進入的次數變少
> ```c
> struct timespec {
> time_t tv_sec; /* seconds */
> long tv_nsec; /* nanoseconds */
> };
> ```
[Linux平臺延時之sleep、usleep、nanosleep、select比較](https://jasonblog.github.io/note/linux_system/linuxping_tai_yan_shi_zhi_sleep_usleep__nanosleep_.html)
```
struct timespec ts = {0, 10};
nanosleep(&ts, NULL);
```
休眠10ns
回顾下秒的换算:ms(毫秒),μs(微秒),ns(纳秒),ps(皮秒)
1s = 1000ms = 1000 * 1000us = 1000 * 1000 * 1000ns = 1000 * 1000 * 1000* 1000ps

./peterson_trival-g

./peterson_correct-O3

./peterson_correct-g

---
## 2. <span class="red">**「確實的」**</span> 解釋「為什麼」 peterson_trival-O3 的執行結果是錯的(問題二)
---
## 3. 請問在你的電腦上「peterson_trival-g」的速度比「 peterson_correct-O3」快或者是慢?上述二個程式的正確與否?
實驗條件: p0 和 p1 沒加 `nanosleep(&ts, NULL);`
### `./peterson_trival-g`

```
$ ./peterson_trival-g
p0: start
p1: start
進入次數(每秒)p0: 4342625, p1: 4340500,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4745797, p1: 4745827,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4872125, p1: 4872167,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4430048, p1: 4430123,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4001208, p1: 4001119,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4823981, p1: 4823978,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 5074670, p1: 5074694,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4332512, p1: 4332196,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 5145434, p1: 5145162,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 5018310, p1: 5018310,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 5032364, p1: 5032388,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 3916238, p1: 3916239,分別執行於 core#0 及 core#7
p1:p0及p1都在critical section
```
### `./peterson_correct-O3`

```
$ ./peterson_correct-O3
start p0
start p1
進入次數(每秒)p0: 2757192, p1: 2737601,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2853137, p1: 2850026,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2794702, p1: 2780973,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2818321, p1: 2805768,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2763920, p1: 2752202,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2799394, p1: 2787686,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2718063, p1: 2717205,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2632451, p1: 2631341,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2667829, p1: 2667185,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2664826, p1: 2663254,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2892686, p1: 2883460,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2818934, p1: 2808839,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2834775, p1: 2829537,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2823886, p1: 2825313,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2862578, p1: 2856812,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2834255, p1: 2824858,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2811785, p1: 2804908,分別執行於 core#3 及 core#0
```
### 比較 「peterson_trival-g」的速度比「 peterson_correct-O3」快或者是慢?
:::info
```
$ ./peterson_trival-g
p0: start
p1: start
進入次數(每秒)p0: 4342625, p1: 4340500,分別執行於 core#0 及 core#7
進入次數(每秒)p0: 4745797, p1: 4745827,分別執行於 core#0 及 core#7
$ ./peterson_correct-O3
start p0
start p1
進入次數(每秒)p0: 2757192, p1: 2737601,分別執行於 core#3 及 core#0
進入次數(每秒)p0: 2853137, p1: 2850026,分別執行於 core#3 及 core#0
```
peterson_trival-g 每秒進入p0 p1次數為 **4百多萬次**
peterson_correct-O3 每秒進入p0 p1次數為 **280萬次~270萬次**
<span class="blue">**因此 peterson_trival-g 的context switch次數速度較快**</span>
:::
實驗方式:
用 `signal(SIGALRM, per_second);` 註冊一個 `per_second()`函式,
設定每1秒觸發一次`per_second()`(量測P0和P1進入CS的次數)
```c
//統計現在正有多少個thread在CS中
int in_cs = 0;
//統計每一個thread進入CS的次數
int p1_in_cs = 0;
int p0_in_cs =0;
//每秒鐘印出P0和P1進入CS的次數
void per_second(int signum) {
static int p0_pre, p1_pre;
printf("進入次數(每秒)p0: %5d, p1: %5d", p0_in_cs - p0_pre, p1_in_cs - p1_pre);
printf(",分別執行於 core#%d 及 core#%d\n", cpu_p0, cpu_p1);
p0_pre = p0_in_cs;
p1_pre = p1_in_cs;
alarm(1);
}
int main(void) {
.....
alarm(1);
signal(SIGALRM, per_second);
.....
}
```
---
## 4. 請 <span class="red">**「確實的」**</span> 解釋「題三」,某個程式比另一個程式快或者慢的理由。
提示:『確實的』我建議**使用組合語言和計算機結構**來解釋
[03-24-perf效能分析講解。](https://www.youtube.com/watch?v=u_LDEGu9hxs&t=2408s)
[HW7 問題四 中間實驗開發過程](https://hackmd.io/u9x4SWp-REq9ifYruOaK5Q)
最後找到成功方法
[羅習五 HW7 perf 分析](https://hackmd.io/A0cLBwCzScaaisxIynxRjQ?view#%E9%97%9C%E9%8D%B5%E8%A6%81%E9%A0%98-%E5%9C%A8-Linux-%E4%B8%8A%E4%BD%BF%E7%94%A8-Perf-%E5%81%9A%E6%95%88%E8%83%BD%E5%88%86%E6%9E%90%E5%85%A5%E9%96%80%E7%AF%87)
> ## 關鍵要領 [在 Linux 上使用 Perf 做效能分析(入門篇)](https://tigercosmos.xyz/post/2020/08/system/perf-basic/)
>
> [Source level analysis with perf annotate](https://perf.wiki.kernel.org/index.php/Tutorial#Source_level_analysis_with_perf_annotate)
> :::success
>
>
> 使用 perf annotate
> ```
> $ sudo perf record ./你指定的執行檔
> $ sudo perf annotate
> ```
> 就能看到組語的效能瓶頸
> 例如
> ```
> $ sudo perf record ./peterson_trival-O3
> $ sudo perf annotate
> ```
>
>
> ---
>
> 使用 perf stat
> ```
> $ sudo perf stat ./peterson_trival-g
> ```
> 就能直接「掌握大局」
> :::
>
> ```
> $ sudo perf stat ./peterson_trival-O3
>
> Performance counter stats for './peterson_trival-O3':
>
> 60,011.23 msec task-clock # 1.999 CPUs utilized
> 413 context-switches # 0.007 K/sec
> 2 cpu-migrations # 0.000 K/sec
> 64 page-faults # 0.001 K/sec
> <not supported> cycles
> <not supported> instructions
> <not supported> branches
> <not supported> branch-misses
>
> 30.014287374 seconds time elapsed
>
> 59.991092000 seconds user
> 0.015996000 seconds sys
> ```
>
> :::success
> **hw7在實機linux上,做perf分析才能真的量到
> cycles,instructions,branches,branch-misses**
> 
>
> ```
> $ sudo perf stat ./peterson_trival-g
>
> Performance counter stats for './peterson_trival-g':
>
> 60,006.22 msec task-clock # 2.000 CPUs utilized
> 580 context-switches # 0.010 K/sec
> 4 cpu-migrations # 0.000 K/sec
> 67 page-faults # 0.001 K/sec
> 211,445,396,951 cycles # 3.524 GHz
> 443,129,572,320 instructions # 2.10 insn per cycle
> 144,841,527,517 branches # 2413.775 M/sec
> 414,350,220 branch-misses # 0.29% of all branches
>
> 30.002342037 seconds time elapsed
>
> 60.006886000 seconds user
> 0.000000000 seconds sys
> ```
> :::