---
# System prepended metadata

title: '2020_OS_Fall_HW1: Benchmark Your Computer Black Box'
tags: [Operating Systems 2020]

---

# 2020_OS_Fall_HW1: Benchmark Your Computer Black Box
###### tags: `Operating Systems 2020`
***繳交期限：09/21-10/06 00:00***

### 作業目標
* 請撰寫一支數值排序的程式，其功能是能夠將數值由小排序到大，且排序的資料量會遠大於電腦記憶體的容量。
* 請觀察及分析程式執行期間，包括但不限於CPU、Memory、Disk I/O的使用情況，探討作業系統是如何服務我們的程式。

---
**學號：** F74071069
**姓名：** 林霆寬
**系級：** 資訊111
#### 開發環境：
* OS：Ubuntu 20.04 虛擬機
* CPU：Intel® Core™ i5-8250U CPU @ 1.60GHz
* Memory：4GB
* Programming Language：C++

#### 程式執行時間：
$5\times10^8$ 筆測資 (約為5.11GB的txt)
![](https://i.imgur.com/4yaWTvL.png)
(單位：秒)

#### 程式開發與使用說明：
首先我先將input.txt分批讀進來，一個批次資料量足夠小使得記憶體能夠進行內部排序，我使用C++ algorithm的sort協助完成內部排序，排序好後的資料再依次依編號存入暫存的txt檔。大檔案拆成各自小檔案排序好後，我使用C++的priority_queue，用min heap的方式協助我完成之後的merge。先將每個檔案的第一個數加進min heap後，跑一個while迴圈。迴圈中，從min heap中取出最小的數字，放進output.txt中。若取出的數字其來源檔案還有未處理數字，則將該數字加進min heap中。若min heap為空，則跳出迴圈，完成merge。

```bash
# Compile
$ g++ -o brenchmark brenchmark.cpp
# Run
$ ./brenchmark [Data Path]
```

#### 效能分析報告：
首先，我先試著改變虛擬機的核心數，觀察硬體核心數的不同是否會影響程式的執行速度，進而推測出作業系統可能的行為。(上面所說的改變虛擬機的核心數量可能會跟真實情況有出入)
以下三張圖片是分別在1核心、2核心及4核心下觀察到的結果，這裡用的是single thread的程式：
* 1核心 
![](https://i.imgur.com/4yaWTvL.png)
* 2核心
![](https://i.imgur.com/9M7J7xU.png)
* 4核心
![](https://i.imgur.com/T0iMDhU.png)
<br>

從以上三張圖可以觀察到，single thread的程式在1核心的表現明顯比在2核心及4核心的表現還要好。再用一張圖片進一步觀察4核心CPU的使用情況，下圖擷取至system monitor：

![](https://i.imgur.com/lQJ9J0H.png)

single thread程式在多核心的環境下，很容易可以觀察到CPU使用率會有此消彼漲的情況。如圖所示，黃色、紅色、綠色線先後達到使用率約100%，推測作業系統因為排程的關係可能會將程式切換到不同處理器上，一些data比方說register file的資料也會藉由external的data path轉移至其他處理器上，我推測這是single thread在多核心環境下跑得比單核心還慢的原因。

於是乎，我用單核心的環境測試此single thread程式，觀察CPU及記憶體使用率的變化，來試圖找出優化方式以及推測作業系統背後可能提供的服務。

![](https://i.imgur.com/cfunBBj.png)

這是我收集資料的指令，先用top指令觀察執行中各個時期的CPU、記憶體使用率，將它匯出成txt檔案，再整理成圖表以觀察變化。

![](https://i.imgur.com/nWxpSgk.png)

我的input.txt為 $5\times10^8$ 筆測資，而我使用的k ways external merge sort的page size是$1\times10^8$ 筆測資，所以我的程式會把 $5\times10^8$ 筆測資的大檔案拆分成 $1\times10^8$ 筆測資sort好的小檔案。從圖中的前半部可以很容易地觀察出有約略5個週期的變化。其中，高的使用率是資料再做sort，而低的使用率是程式在讀寫檔案。後半部CPU的使用率則大致上都是在80%以下。由此可見sort的計算需求是相對較大的，於是程式對於硬體的優化我試著從此下手。

我採用multithread的程式設計來優化，降低CPU的閒置資源，增加計算速度。這邊使用data parallelism的方式，使用C language的pthread，將一段記憶體拆成n段，分給n個thread進行排序。

下表為 $1\times10^7$ 筆測資，n個thread，只收集純sort的秒數：



| n (thread) | 1 | 2 | 4 | 6 | 8 |
| -------- | -------- | -------- | -------- | -------- | -------- |
| 時間 (秒)     | 2.132     | 600以上     | 210     | 0.717     | 0.294     |

平均下來，6 threads和8 threads的時間比singel thread來得好，而2 threads和4 threads很突兀的時間遠高於single thread的好幾倍，我推測是資料量不夠大，用少量的threads中間link的成本太高，以及寫法的關係，pthread_join需要時常等待全部threads做完。除此之外，8 threads標準差過大，有時會測到40、50秒的秒數，整體下來，data parallelism沒有很明顯的優化。

![](https://i.imgur.com/y9HOazF.png)

至於記憶體的使用率，整個執行時間下來都在10%以下，前半部因為陣列以及sort遞迴，使用率比較高，而後半部只用了min heap來merge，使用率很低。但整體下來，記憶體的使用率不高，作業系統還有保留許多閒置資源。
![](https://i.imgur.com/hino9io.png)

**同時測試多支程式：**
這裡以2支程式同時執行來觀察：

![](https://i.imgur.com/KlYGYPt.png)

![](https://i.imgur.com/7pUhUjX.png)

![](https://i.imgur.com/ulfh9x2.png)

可以觀察到，同時執行兩個程式，閒置資源一樣多，但是時間慢了許多，兩支程式要搶CPU及HDD IO 資源。

**結論OS的設計要提供哪些優化服務：**
我認為作業系統CPU方面排程可以讓CPU使用率大的程式優先順位高一點，盡量在該程式CPU使用率低的時候，比方說memory IO，空出CPU資源，當CPU使用率高的時候，減少CPU的切換，才能增加效率。而記憶體方面，當有閒置資源時，可以減少閒置資源，增加記憶體使用率，減少虛擬記憶體。
