Try   HackMD

2016q3 Homework3 (mergesort-concurrent)

contribute by <petermouse>

開發環境

  • OS:Lubuntu 16.04 LTS
  • Memory: 8 GB
  • CPU:
    • Name:
      • Intel® Core i5-4200H CPU @ 2.80GHz
    • Cache:
      • L1d Cache: 32K
      • L1i Cache: 32K
      • L2 Cache: 256K
      • L3 Cache: 3072K

mergesort-concurrent

理解程式架構&Refactoring

Makefile

首先,先看Makefile以及make看看

gcc -std=gnu99 -Wall -g -pthread -o list.o -MMD -MF .list.o.d -c list.c
gcc -std=gnu99 -Wall -g -pthread -o threadpool.o -MMD -MF .threadpool.o.d -c threadpool.c
gcc -std=gnu99 -Wall -g -pthread -o main.o -MMD -MF .main.o.d -c main.c
gcc -std=gnu99 -Wall -g -pthread -o sort list.o threadpool.o main.o -rdynamic

-M:顯示關聯的檔案
-MM-M但忽略#include內的關聯
-MMD-MM但將結果寫入檔案(.d)中
-MF [file]-M -MM但指定檔名位置
-rdynamic參考資料,我還是看不懂待釐清

list.c/h

這裡定義了node_t的struct type
內含一個value以及表示下一個node的node_t指標
以及llist_t代表一個起始點的node指標與list大小

比較特別的是:

typedef intptr_t val_t;

因為不同的系統會有不同的size大小 (參考C語言指標轉換為intptr_t型別)
所以將指標位置以intptr_t儲存才比較有可攜性

還有定義一些關於linked list的操作函式。

threadpool.c/h

這裡定義了task以及threadpool的type,還有相關的函式,跟第二週看到的mbrossard好像啊!不過跟實際還是有落差就是了。

在程式碼中task queue是用linked list做連結,push函式中可以看到新加入的task->next會link至head,在變成head,tail則是最早加入的node。
這樣跟我們對於queue的認知是相反的:head最先處理,tail最後,因此是名詞剛好相反,所以我把tqueue相關函數的headtail對調。

另外,我也把task_t中last改成prev,兩個都可以解釋成「上一個」,但prev更清楚。

typedef struct _task { void (*func)(void *); void *arg; struct _task *next, *prev; } task_t;

再來,在tqueue_pop的函式中,是將head指向的task移除

ret = the_queue->head; if (ret) { the_queue->head = ret->prev; if (the_queue->head) { the_queue->head->next = NULL; } else { the_queue->tail = NULL; } the_queue->size--; }

可以發現
在vim中可以很簡單的辦到::1,$s/word/replace_word/g可將所有word取代成replace_word
1.$:重頭至尾
g:每一行每個符合的都處理

參考資料

gcc 參數詳解
gcc preprocessor options
gcc link options
-rdynamic
C語言指標轉換為intptr_t型別
vim中的置換