# 羅習五 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> 解釋「題三」,某個程式比另一個程式快或者慢的理由。 提示:『確實的』我建議**使用組合語言和計算機結構**來解釋 ::: 系統環境 ![](https://hackmd.io/_uploads/rJAFfiCQh.png) ``` $ 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 ![](https://hackmd.io/_uploads/rJFcfoAXn.png) ./peterson_trival-g ![](https://hackmd.io/_uploads/r1rifsCX3.png) ./peterson_correct-O3 ![](https://hackmd.io/_uploads/rk6oziRQ2.png) ./peterson_correct-g ![](https://hackmd.io/_uploads/SJM6fsAQn.png) 沒多久會進入 ``` p0:p0及p1都在critical section p1:p0及p1都在critical section ``` ![](https://hackmd.io/_uploads/Bk3TfsAQ3.png) ### 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 ![](https://hackmd.io/_uploads/rJ_MXjRm3.png) ./peterson_trival-g ![](https://hackmd.io/_uploads/B1477sCXh.png) ./peterson_correct-O3 ![](https://hackmd.io/_uploads/r1i7Qj0Q3.png) ./peterson_correct-g ![](https://hackmd.io/_uploads/Hkm4QjR7h.png) --- ## 2. <span class="red">**「確實的」**</span> 解釋「為什麼」 peterson_trival-O3 的執行結果是錯的(問題二) --- ## 3. 請問在你的電腦上「peterson_trival-g」的速度比「 peterson_correct-O3」快或者是慢?上述二個程式的正確與否? 實驗條件: p0 和 p1 沒加 `nanosleep(&ts, NULL);` ### `./peterson_trival-g` ![](https://hackmd.io/_uploads/BJkHQi0Xn.png) ``` $ ./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` ![](https://hackmd.io/_uploads/rJqB7jAmn.png) ``` $ ./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** > ![](https://hackmd.io/_uploads/BJzwQoCm2.png) > > ``` > $ 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 > ``` > :::