# 2017q1 Homework1 (compute-pi) contributed by < `laochanlam` > ###### tags: `laochanlam` ### Reviewed by `yanglin5689446` - OpenMP4 的資料圖明顯跟其他方式相差很大,是否有個合理的解釋? - 執行的時候是否有其他因素影響到 performance ,使得圖看起來不太規律? - ### Reviewed by `Daichou` * 實驗數據在100~95100的資料是否有偏差資料,尤其是openmp4。 ### Reviewed by `Billy4195` * leibniz法可以加上平行化的後的加速,以及跟原本PI的算法做比較。 * [疑問]為什麼OpenMP4的N與時間的圖會有上下起伏呢? ## 開發環境 - Ubuntu 16.10 (64bit) ``` Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 61 Model name: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz Stepping: 4 CPU MHz: 2400.878 CPU max MHz: 3000.0000 CPU min MHz: 500.0000 BogoMIPS: 4788.90 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 4096K NUMA node0 CPU(s): 0-3 ``` ## 相關連結 - [2017 年春季作業說明](https://hackmd.io/s/Bk-1zqIte#) - [2017q1 Homework1 (作業區)](https://hackmd.io/MYJjEYGZITgWgOwCMAmw4BYYwAxyQQKxwBmwGOkAHMDeEgGxA===?view) - [B03: compute-pi 作業要求](https://hackmd.io/s/HkiJpDPtx) - [compute-pi Github連結 ( laochanlam ) ](https://github.com/laochanlam/compute-pi) - [作業解說 video](https://www.youtube.com/watch?v=m1RmfOfSwno) - [課程進度與開放資源 Wiki](http://wiki.csie.ncku.edu.tw/sysprog/schedule) ## Compute-pi 開發紀錄 先是按照作業要求重現一次實驗,把專案 clone 下來後,打開 **computepi.c** 可以清楚看到各種計算 pi 的不同優化版本。 分別為 **baseline** 版本, **AVX SIMD** 版本, **AVX SIMD** + **Unroll looping** 版本及 **OpenMP** ( 2 threads & 4 threads) 版本。 <br> 接著開始輸入 ```$ makecheck``` 及 ```$ make gencsv```後,得到 result_clock_gettime.csv 這樣的數據,準備用 LibreOffice 繪圖。 在繪圖之前,先要搞懂資料的產生過程。 ```make gencsv: default for i in `seq 100 5000 25000`; do \ printf "%d," $$i;\ ./benchmark_clock_gettime $$i; \ done > result_clock_gettime.csv ``` 在Makefile中有這一段,看起來像是 Shell script 的東西,來研究一下。 ```make for i in `seq 100 5000 25000`; ``` 這一段就是i初始為 100 ,每執行多一次增加 5000 ,到 25000 就停止,所以一共會執行 5 次分別為 100 , 5100 , 10100 , 15100 , 20100 。 <br><br> 然後我把實驗數據改為100~95100,並用 LibreOffice 繪出圖像如下。 ![Imgur](http://i.imgur.com/hHgNrFB.png =700x) 然後嘗試寫 gnuplot 的 script 畫圖。 因為 result_clock_gettime.csv 中用逗號作間隔,再加上各種對 gnuplot 的不熟悉,畫個圖快畫了我半個小時Orz。 ![Imgur](http://i.imgur.com/Ax7A0Ml.png) 本來我是用 ```"%lf,%lf,%lf,%lf,%lf,%lf"``` 來實現逗號分隔的數據讀取,但後來找到[petermouse學長的共筆](https://hackmd.io/s/Hk2DSIYp)有更好的方法,就是 ```set datafile separator ","``` 即可實現逗號分隔。 附上程式碼供參考: ```gnuplot reset set ylabel 'time(sec)' set style data lines set title 'Compute-pi' set term png enhanced font 'Verdana,10' set output 'runtime.png' set xtics rotate by 45 right set datafile separator "," plot [:][:0.05]'result_clock_gettime.csv' using 1:2 title 'Baseline', \ '' using 1:3 title 'OpenMP ( 2 threads )', \ '' using 1:4 title 'OpenMP ( 4 threads )', \ '' using 1:5 title 'AVX', \ '' using 1:6 title 'AVX + Unroll looping', \ '' using 1:7 title 'Leibniz' ``` ### Leibniz formula for π 證明 參考[shelly4132的共筆](https://hackmd.io/s/HJrLU0dp)的証明方法, 先有以下分解: ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/c6358998bd99e608b5066ceda18a5211aae91472) 對兩邊進行從 0 到 1 的積分, ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/d84dabc013f1b57c1d047303d68e28b3054c52e1) 當n趨向無限時, ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/4fbcf3489c4ce0a4f161b2584ec1f31c70cbc5a6) ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/39b589297ef09eb07ad5c8acf06523fc4216ff45) 得証 ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/8283f454140077256b47afadd702fed4b3b56569) <br><br> 最後編寫程式並繪圖。 ```C double compute_pi_leibniz(size_t N) { double pi = 0.0; double term = 0.0; double sign = 1.0; for (size_t i = 0; i < N; i++) { term = (double) sign / ( 2.0 * i + 1.0 ); sign = -sign; pi += term; } return pi * 4.0; } ``` ![Imgur](http://i.imgur.com/egnFB7X.png) 接下來等待有時間再進行其它優化。 --- ## 補充知識 - [x] time - [x] error rate --- ## time ### Wall-clock time >Wall-clock time 顧名思義就是掛鐘時間,也就是現實世界中實際經過的時間,是由 kernel 裡的 xtime 來紀錄,系統每次啟動時會先從設備上的 RTC 上讀入 xtime。 通常來說並不建議用來量測程式時間。 ### CPU time >CPU time 指的是程序在 CPU 上面運行消耗 (佔用) 的時間,clock() 就是很典型用來計算 CPU time 的時間函式,但要注意的是,如果有多條 threads,那 CPU time 算的是「每條 thread 的使用時間加總」。 <br> 當我們執行 ```$ time``` 時,會得出以下三個參數: **real time** : Wall-clock time,注意這個時間會被執行中的其他程式所影響。 **user time** : 程式在 user mode 佔用所有的 CPU time 總和(若是多核計算時間會加總) **sys time** : 程式在 kernel mode 佔用所有的 CPU time 總和。 #### 參考及引用資料 [B03: compute-pi](https://hackmd.io/s/HkiJpDPtx#) --- ## error rate 在[廖健富學長提供的詳盡分析](https://hackpad.com/Hw1-Extcompute_pi-geXUeYjdv1I)中計算 error rate 的函式是這樣的。 ```c // Error rate calculation #define M_PI acos(-1.0) double pi = compute_pi(n); double diff = pi - M_PI > 0 ? pi - M_PI : M_PI - pi; double error = diff / M_PI; ``` 裡面是用了 arccos -1 來求 pi ,然後算它跟每個版本的誤差值來求 error rate。 #### 參考及引用資料 [廖健富學長提供的詳盡分析](https://hackpad.com/Hw1-Extcompute_pi-geXUeYjdv1I) --- ## 進度 - 2017/03/01 - 重演實驗,並用 gnuplot畫圖