# 2016q3 Homework2 (phonebook-concurrent) contributed by <`finalallpass`> ### 開發環境 * 由lscpu得到的結果 ``` Architecture: x86_64 CPU 作業模式: 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 每核心執行緒數:1 每通訊端核心數:4 Socket(s): 1 NUMA 節點: 1 供應商識別號: GenuineIntel CPU 家族: 6 型號: 94 製程: 3 CPU MHz: 835.367 BogoMIPS: 4605.92 虛擬: VT-x L1d 快取: 32K L1i 快取: 32K L2 快取: 256K L3 快取: 6144K NUMA node0 CPU(s): 0-3 ``` * 閱讀資料 * 先詳細閱讀老師給的資料。[參考資料](https://hackmd.io/s/H10MXXoT) * 還有社團中的共筆。[tundergod共筆](https://hackmd.io/s/rk5IVI0a) >> 使用lscpu之後顯示我電腦的thread per core是1,所以以我電腦為四核心來說能夠支援最多thread數應該是4,但在作業一時thread數設為8甚至16時效能明顯比4好,這跟我預想的不太一樣阿!! [name=顏子皓] >> 太好了,表示你可以設計更多的實驗來釐清,learning by doing! [name=jserv] ### Concurrency (並行) vs. Parallelism (平行) * 上課時老師也有問到這個問題,concurrency是有單一的processor去解決兩個或以上的問題、程序,parallelism是將單一個問題、程序分給多個processor解決。在如今多核心已經很普遍的現在,concurrency是個比較值得深入探討的問題。 ### POSIX Threads * 十分感謝有繁體中文的內容可以讀阿。[Getting Started With POSIX Threads 宋振華](http://www.csie.ntu.edu.tw/~r92094/c++/pthread.txt) * 研究thread pool在C中的實作。[Github](https://github.com/mbrossard/threadpool) * 建立threadpool.c和threadpool.h。 ``` threadpool的結構 struct threadpool_t { pthread_mutex_t lock; pthread_cond_t notify; pthread_t *threads; threadpool_task_t *queue; int thread_count; int queue_size; int head; int tail; int count; int shutdown; int started; }; ``` ### mmap * 去了解mmap的使用方法。函式原型宣告為: ``` void *mmap(void *start,size_t length, int prot, int flags, int fd, off_t offsize); ``` * 其中參數flags在程式中用到的為MAP_SHARED:允許其他映射該檔案的行程共享,對映射區域的寫入資料會複製回檔案。 >> 尊重我們的傳統文化,請用台灣慣用技術術語!file = 檔案 (不是「文件」),data = 資料 (不是「數據」) [name=jserv] >> 老師抱歉已經修正,之後會多加注意。[name=顏子皓] ``` int fd = open(ALIGN_FILE, O_RDONLY | O_NONBLOCK); char *map = mmap(NULL, fs, PROT_READ, MAP_SHARED, fd, 0); ``` ### 實作 * threadpool_t *threadpool_create(int thread_count, int queue_size, int flags):用這個來產生threadpool,第一個參數指定thread數目,第二個指定queue長度。 * int threadpool_add(threadpool_t *pool, void(*routine)(void*), void arg, int flags):用來增加thread,第二個參數為對應的函數指標。 * int threadpool_destory(thread_t *pool, int flags):摧毀所有的thread,後面flags可以指定是否立刻結束或是等待所有thread皆完成後再中止,但期間不能再添加thread。 * [上方githib的詳細說明](http://blog.csdn.net/jcjc918/article/details/50395528) * 在main中建立threadpool。這裡我們選擇用graceful shutdown。 ``` threadpool_t *pool = threadpool_create(THREAD_NUM, 512 , 0); for( int i = 0 ; i < THREAD_NUM ; i++ ){ app[i] = new_append_a(map + MAX_LAST_NAME_SIZE * i,map + fs, i, THREAD_NUM, entry_pool + i); pthread_mutex_unlock(&lock); } threadpool_destroy(pool, 1); ``` * 得到結果 ``` size of entry : 24 bytes execution time of append() : 0.003680 sec execution time of findName() : 0.003339 sec ``` * 然後將thread更改, THREAD_NUM = 1, 4, 8, 16, 32, 64。 ![](https://i.imgur.com/vBEz9Rs.png) * 這裡發現append time的時間並沒有因為thread數目而提高效率,反而需要更多的時間。感覺應該不是正確的結果。 * 但是這個和我上次所疑惑的東西卻是符合的結果,我的CPU可執行的thread數目是4*1個,所以照裡來說在thread數為4的時候會有較佳的效率。那這張圖也剛好符合這個推論,低於4和高於4的效能都較差。可能還需要更多實驗來驗證。 ###### tags: `phonebook-concurrent`