施雨妏
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 2016q3 Homework2 (phonebook-concurrent) contributed by <`ruby0109`> > 反省這兩個禮拜糟糕的自己, 完全不行阿QAQQQ > 參考了[CheHsuan](https://hackmd.io/s/rJPYFYRa) 和 [TempoJiJi](https://hackmd.io/s/rymKa4aT)兩位同學的筆記之後, 發現自己沒有驗證原本的程式正確性, mmap沒有下去探討, 學習thread pool等沒有先從小程式實作,和遇到問題不會拆解所以卡住。以下加入預期目標, 繼續完成作業。 之前進度:[phonebook](https://hackmd.io/BwIwLAjApgZgJgVgLQCYEHYCcSwOAQyUxHwhymAhgDYBmRGBfIA=) ## 預期目標 * 學習驗證程式正確性 * concurrency 認知整理 * 學習其他人共筆 * thread pool ## 理解作業程式碼 ### 影片 開始實作之前, 我先看了[吳彥寬同學程式解說video](https://www.youtube.com/watch?v=sWtWslsr4Ac), 筆記如下: * `fgets` 本身就可以讀行, 所以可以簡化 :::info 補充fgets基礎知識: 根據c99 規格書, `#include <stdio.h>` `char *fgets(char * restrict s, int n,FILE * restrict stream);` description: The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additionalcharacters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array. ::: 理解: fgets讀取stream指向的stream最多n-1個字元到s指向的陣列中, 遇到換行符號或是檔案結尾字元就不會再讀, '\0' 會寫在陣列最後一個字元之後。 * `strncasecmp`: :::info #include <strings.h> int strcasecmp(const char *s1, const char *s2);int strncasecmp(const char *s1, const char *s2, size_t n); from linux manual: strcasecmp() :function compares the two strings s1 and s2, ignoring the case of the characters. It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2.The strncasecmp() function is similar, except it compares the only first n bytes of s1 ::: strncasecmp比較s1前n bytes和s2, 比較時忽略大小寫, 若s1和s2相同傳回0; s1長度大於s2傳大於0值; 小於則傳負值。 * ~~memory pool 和 pthread 這兩個部份看影片仍然不太明白~~ * ~~可以在findname放其他資料,而不是在append整個放進去~~(findname或許會些微上升, 可是不會很多)append進去的只有lastName 的指標, findname時再放入lastName * 整個append用pthread下去做而不是只有mmap(還不懂為什麼原本只做mmap時間會上升) ### **檢測程式正確性** * 先執行一次看看, make plot之後: Performance counter stats for './phonebook_orig' (100 runs): 4,457,101 cache-misses # 91.778 % of all cache refs( +- 0.07% ) 4,856,373 cache-references ( +- 0.05% ) 263,262,629 instructions # 1.69 insns per cycle ( +- 0.02% ) 155,898,150 cycles ( +- 0.06% ) 0.076228638 seconds time elapsed ( +- 0.31% ) Performance counter stats for './phonebook_opt' (100 runs): 3,548,725 cache-misses # 61.592 % of all cache refs( +- 0.25% ) 5,761,661 cache-references ( +- 0.46% ) 224,875,100 instructions # 1.93 insns per cycle ( +- 0.04% ) 116,299,224 cycles ( +- 0.42% ) 0.278607164 seconds time elapsed ( +- 2.06% ) 優化後的cache miss略下降一些。 ![](https://i.imgur.com/wMmao18.png) * file align 先看在main.c中被include的file.c產生的align.txt, 直接點開的話裡面只有aaaa,用vim 的話則是: ```= aaaa ^@^@^@^@^@^@^@^@^@^@^@aaaaa ^@^@^@^@^@^@^@^@^@^@aaaaaa ^@^@^@^@^@^@^@^@^@aaaaaaa ^@^@^@^@^@^@^@^@aaaaaaaa ^@^@^@^@^@^@^@aaaaaaaah ^@^@^@^@^@^@aaaaaaauugh ^@^@^@^@aaaaaagh ^@^@^@^@^@^@^@aaaaaahhhhh ^@^@^@^@aaaaaaugh ^@^@^@^@^@^@aaaaagh ^@^@^@^@^@^@^@^@aaaaah ^@^@^@^@^@^@^@^@^@aaaarthur ^@^@^@^@^@^@aaaaw ^@^@^@^@^@^@^@^@^@^@aaagghhhh ^@^@^@^@^@^@aaah ^@^@^@^@^@^@^@^@^@^@^@aaaugh ^@^@^@^@^@^@^@^@^@aaccf ``` 不是很懂^@是什麼, 參考[what is ^@ character in vi?](http://stackoverflow.com/questions/21569165/what-is-character-in-vi)才知道是NULL bytes。不過奇怪的是,首先第一行沒有^@,再來每一行的行數不同,像第7行有17個,第8行只有12個。 先用GDB觀察main.c跳進file_align function後的執行情形。在wbuf和rbuf都有align, 顯示出來的值也都正確。rbuf的大小似乎可以調小一點, 畢竟也有措施避免strcpy的overflow。 * linked list的資料是否正確 試試看原本同學寫的debug.h,跑完之後發現在終端機不太方便測試是否有遺漏的資訊, ~~要怎麼比對呢?~~ 可以直接用findname ```clike // use findname to test whether all elements in the list // open file for test and origin word.txt FILE *test,*org; test = fopen("test","a"); org = fopen(DICT_FILE, "r"); char line[MAX_LAST_NAME_SIZE]; // use findname to test whether all elements in the list while(fgets(line, sizeof(line),org)){ e = pHead; if(findName(line, e) == NULL) fprintf(test,"%s not found\n",line); } fclose(org); fclose(test); ``` 直接把words.txt檔的東西丟下去找, 可是這樣若找尋350000筆,每筆0.03897要尋找約22分鐘。發現[TempoJiJi](https://hackmd.io/s/rymKa4aT)大大直接另外寫一個測, 才發現原來這個版本沒有Hash 寫了entry_test.c 可是有segmentation fault debug還是卡了好久, 用GDB下去看發現是在append_target中, 第60行的地方, malloc執行到第三個word就會直接掛掉。 把他改成小一點的程式, 縮小錯誤範圍: ```clike= #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #define MAX_LAST_NAME_SIZE 16 #define HASH_SIZE 42737 #define DICT_FILE "./dictionary/words.txt" typedef struct __PHONE_BOOK_ENTRY { char *lastName; struct __PHONE_BOOK_ENTRY *pNext; } entry; entry *append_target(char lastName[], entry *e) { e->pNext = (entry *)malloc(sizeof(entry)); e = e->pNext; strcpy(e->lastName, lastName); e->pNext = NULL; return e; } int main(void) { FILE *org; org = fopen("./dictionary/words.txt","r"); char line[MAX_LAST_NAME_SIZE]; entry *target, *tHead; tHead = (entry *)malloc(sizeof(entry)); target = tHead; target -> pNext = NULL; while(fgets(line,sizeof(line),org)) { target = append_target(line,target); } fclose(org); free(tHead); free(tHead->pNext); } ``` gdb跑出的結果: Program received signal SIGSEGV, Segmentation fault. __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:605 605 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: 沒有此一檔案或目錄. 發現是struct 忘記改>< 感謝徐朝逸大大幫我看codeQAQ 幾經波折, 把所有菜鳥可以犯的錯犯過一遍然後debug完後, 發現有一長串都沒有在裡面, 這裡擷取一小部份: aaaa not found angelika not found anklet not found antescript not found antirobin not found assiento not found 發現我的程式是錯的!!雖然有幾個字母帶進原程式會發現的確沒在裡面, 可以很多都是跑得出來的。把append和findname找不到的資料互相比較, 發現其實有append進去, 可是findName沒有找到, 原來是findName的地方有寫錯, 這樣代表之前自己的code也有錯... * 正確性解決 把程式改好之後, 跑出來的結果: aaaa not found aaaaa not found aaaaaa not found aaaaaaa not found 因為pthrea跑的方式是 thread0:0 4 8.. thread1:1 5 9.. thread2:2 6 10.. thread3:3 7 11.. 所以可以推測這可能是pthread各自list的開頭有問題。 仔細看之後發現在main.c 中的pHead = stack[i]->pHead->pNext和etmp->pNext = stack[i]->pHead->pNext 應該要把pNext去掉!! ## 實作可以改良的地方 * 在語法的部份: ```clike if ((suffix = (pad - strlen(rbuf))) != 0) strcpy(wbuf, rbuf); ``` 應該要大於0, 以防超過陣列大小 * 沒有註解看起來好痛苦QAQQ : 加入註解 * 變數在main.c中和.c file不好對照, 有點難讀 * 把new_append_a改成ThrdInitial(char *StartAdrs, char *EndAdrs, int tid, int nthrd, entry *pptr) * append_a改成 ```clike typedef struct _Thread_Stack_ { char *StartAdrs; char *EndAdrs; int tid; int nthread; entry *PoolPtr; entry *pHead; entry *pTail; } ThrdStack; ``` ## concurrency 筆記: * [Concurrency is not Parallelism](https://blog.golang.org/concurrency-is-not-parallelism), by Rob Pike * sometime people run a program with may processes, but it gets slow, why? what is concurrency? * concurrency in computer world is a way to build things, concurrent is a composition of independently executing things typically funcitons but they don't have to be(independently executing processes)這裡的process泛指各種thread, coroutine等 **理解**:concurrency就像是一種方法, 由各個獨立執行的函式(包含process, thread, coroutine?等等)組成, 可是方法不一定要採用。 * parallelism is simultaneously executing lots of multiple thing, possible related possible not **理解**:parallelism是同時執行很多東西,可能相關,也可能互相獨立。 * concurrency is about dealing with a lot of things at once and parallelism is about doing a lot of things at once **理解**:concurrency是一次處理很多東西, 但不一定要同時執行, parallelism 就是同時執行很多東西。 * concurrency is about the structure parallelism is about the execution * concurrency is a structure things that you can maybe use parallelism to do a better job but parallism is not the goal of concurrency concurrency's goal is a good structure ex. OS deal with lots of things, but these things aren't necessarily parallel, only one processor only one of them is ever running the time, so there are concurrencty structure, but not necessary parallel **理解**:parallism不是concurrency的目標, 就像是OS也是一次處理很多東西, 而且不一定要都同時執行。也就是concurrency是一個結構,可是不一定要用parallism的方式執行。 * parallelism像是一個箭頭,可以分成不同的方向 * concurrency gives you a structure program different pieces, but we need to find out how to coordinate those pieces and communication **理解**:concurrency給我們一個架構, 可以把程式分成不同的區塊, 可是我們必須找出怎麼協調和讓這些區塊可以溝通 後面的GO就聽不是很懂了>< * [The Free Lunch Is Over](http://www.gotw.ca/publications/concurrency-ddj.htm) A Fundamental Turn Toward Concurrency in Software By Herb Sutter * 這30年來, CPU 設計者主要藉由改善以下來達到效能的提昇 * clock speed * execution optimization-為了改善效能, 甚至會有風險改變程式 * pipelining * branch prediction * executing multiple instructions in the same clock cycle(s) * reordering the instruction stream for out-of-order execution. * cache * 可是發展到了現在 clock speed很難再提昇, 因為如果再提昇會有無法散去高熱, 太耗能跟電流液出的情形 * Myths and Realities: 2 x 3GHz < 6 GHz * 即使有兩個thread在兩個實體處理器上運作, 也不會得到兩倍的效果, 為什麼呢? * 要維持cache coherency * 除非兩個core在跑不同的程式, thread run independently所以不需要等待彼此不然這些core不會被良好的運用 * 雖然系統還是會被潛在的廣告軟體和間諜軟體佔用 * 未來可以藉由以下來繼續提高效能 * hyperthreading- 在一個CPU上運行數個thread in parallel * 但仍然只有一個 cache, 一個 integer math unit, 一個 FPU, and in general just one each of most basic CPU features. * 很難提昇兩倍效能, 而且對於single-threaded應用沒有幫助。 * multicore * 很難提昇兩倍效能, 而且對於single-threaded應用沒有幫助。 * cache * 應該可以繼續成長,因為space is speed * 一個cache miss就要多花10~50倍的時間(相較於去cache拿data) * Concurrency is the next major revolution in how we write software * [Concurrency的Youtube Lecture](https://www.youtube.com/watch?v=iKtvNJQoCNw&list=PLrWfHqCHBgVJ4jPMXnv2tbB6zg5uegbc3&index=3) * Locks: 擁有權, 擁有者才能unlock。 作業中的concurrency: * 第一次看到pthread_setconcurrency, 查manual理解之下是在linuxthread沒有太大作用, 可是可以增加相容性。 ## 學習其他人共筆 [LanKuDot (李昆憶)共筆](https://hackmd.io/s/HJFhaiAp) * 參考筆記並閱讀[The Free Lunch Is Over](http://www.gotw.ca/publications/concurrency-ddj.htm), [對於重構的兩則常見誤解](http://www.ithome.com.tw/node/79813) * valgrind: * 安裝:$ sudo apt-get install valgrind * 說明:$ valgrind --help * 參考資料:[分析工具valgrind的使用](http://ottoshare.blogspot.tw/2012/03/valgrind.html)(這篇的指令tools要改成tool),[Valgrind is *NOT* a leak checker](http://maintainablecode.logdown.com/posts/245425-valgrind-is-not-a-leak-checker) * 用途: * 偵測undefined behavior ```valgrind ./phonebook_opt``` * function and memory profiler * ==data-race detection==(覺得這好酷!!) ```valgrind --tool=helgrind ./phonebook_opt``` * 可以用來看memory leak ``` --leak-check=full``` ==14872== Memcheck, a memory error detector ==14872== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==14872== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==14872== Command: ./phonebook_opt ==14872== size of entry : 24 bytes execution time of append() : 0.118666 sec execution time of findName() : 0.002815 sec ==14872== ==14872== HEAP SUMMARY: ==14872== in use at exit: 2,215 bytes in 16 blocks ==14872== total heap usage: 28 allocs, 12 frees, 8,408,637 bytes allocated ==14872== ==14872== 16 bytes in 1 blocks are definitely lost in loss record 1 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x400F23: file_align.4663 (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x40101B: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 16 bytes in 1 blocks are definitely lost in loss record 2 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x40166E: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x4013F6: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 16 bytes in 1 blocks are definitely lost in loss record 3 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x40166E: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x40142A: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 16 bytes in 1 blocks are definitely lost in loss record 4 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x40166E: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x40147E: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 24 bytes in 1 blocks are definitely lost in loss record 5 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x401050: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 107 bytes in 1 blocks are definitely lost in loss record 8 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x4016B1: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x4013F6: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 107 bytes in 1 blocks are definitely lost in loss record 9 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x4016B1: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x40142A: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 107 bytes in 1 blocks are definitely lost in loss record 10 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x4016B1: findName (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x40147E: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== 192 bytes in 4 blocks are definitely lost in loss record 11 of 13 ==14872== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==14872== by 0x401709: ThrdInitial (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== by 0x4011EC: main (in /home/ruby/2016_autumn/W2/phonebook-concurrent/phonebook_opt) ==14872== ==14872== LEAK SUMMARY: ==14872== definitely lost: 601 bytes in 12 blocks ==14872== indirectly lost: 0 bytes in 0 blocks ==14872== possibly lost: 0 bytes in 0 blocks ==14872== still reachable: 1,614 bytes in 4 blocks ==14872== suppressed: 0 bytes in 0 blocks ==14872== Reachable blocks (those to which a pointer was found) are not shown. ==14872== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==14872== ==14872== For counts of detected and suppressed errors, rerun with: -v ==14872== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 0 from 0) * 問題:看到一些文章說free並不是必須, 可是大部分是好的, 比如[In C, is it necessary to free a pointer at exit?](http://stackoverflow.com/questions/3126122/in-c-is-it-necessary-to-free-a-pointer-at-exit), [What REALLY happens when you don't free after malloc?](http://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc?rq=1), [Does calling free or delete ever release memory back to the “system”](http://stackoverflow.com/questions/1421491/does-calling-free-or-delete-ever-release-memory-back-to-the-system) 要視情況而定, 可是有種很難體會的感覺。 * Solve memory leak * 在findName中, 不需要把lastname放進entry->lastName 中, 因為strncasecmp就是用pointer即可。 * 學習李昆憶大大的重構方式 * 在每個段落加上這個段落的作用, 比如file preprocessing, release the memory等等方便看的人快速理解程式內容 * 把在程式碼中的indlude header移到最上方 * 用參數讓輸入進函式的資料更容易解讀 * 去掉不需要的參數如etmp * 改掉dprintf * 優化append * 原本是12341234的方式(row-major) * 改成把資料分成四大段, 符合cache的排列方式 結果: ![](https://i.imgur.com/9d1PdsX.png) ### Thread Pool * 參考[C 的 Thread Pool 筆記](http://swind.code-life.info/posts/c-thread-pool.html) * 以下使用[threadpool-mbrossard](https://github.com/mbrossard/threadpool)的程式碼 * 理解ThreadPool 這個程式看起來好舒服!!!原來這就叫做程式碼><!! * 理解過程中程式筆記 * 在每個function前說明function作用, 和argument說明 * 學到goto用法 * 原來可以這樣寫:pool->head = pool->tail = pool->count = 0; * 程式運作: 先來看wiki 使用thread pool處理Task的圖 ![](https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Thread_pool.svg/580px-Thread_pool.svg.png) 再來看程式的struct, 首先threadpool中會紀錄兩個array, 一個是threads另一個是task queue。 ```clike struct threadpool_t { pthread_mutex_t lock; pthread_cond_t notify; pthread_t *threads;//放置所有thread空間的指標 threadpool_task_t *queue;//放置所有task空間的指標 int thread_count; int queue_size; int head; int tail; int count; int shutdown; int started; }; ``` threads的struct是pthread_t; task queue的struct則是由funciton和argument組成 ```clike typedef struct { void (*function)(void *); void *argument; } threadpool_task_t; ``` 再來看執行的流程圖 ```flow st=>start: threadpool_create 決定好thread的數量和task queue的最大值 e=>end: Thread pool destroy op=>operation: thread開始執行(threadpool_thread) op2=>operation: thread搶mutex lock cond=>condition: 某個thread搶到之後 裡面是否有task? op7=>operation: op3=>operation: 從task queue拿task之後離開, unlock op4=>operation: 下一個thread進來 op5=>operation: pthread_cond_wait 等待threadpool_add的訊號, 同時unlock, 讓其他thread進來一起等待 op6=>operation: threadpool_add pthread_cond_signal新增task, 剛剛搶到lock的thread開始工作 st->op->op2->cond cond(yes)->op7->op3->op4->e cond(no)->op5->op6->op3->e ``` 不懂的地方: ~~next = (pool->tail + 1) % pool->queue_size; pool->head = (pool->head + 1) % pool->queue_size;~~ 上面這個是像一個ring, 有head和tail在兩端移動 * Implementation * 在implement的時候, 我遇到的問題是不知道thread pool的大小要設多大, 參考[TempoJiJi](https://hackmd.io/s/rymKa4aT)是8, 先試試看 * 把thread pool大小設成thread的兩倍大 ![](https://i.imgur.com/4GzHVnz.png) 從圖上可以發現四個thread的時候最快, 8個以上時間就變得相當高 改進: * 學習github.ignore * 參考資料-[Git 教學(1) : Git 的基本使用](http://gogojimmy.net/2012/01/17/how-to-use-git-1-git-basic/) * vim .gitignore 裡面加上想要忽略的檔案 * thread pool影響 * 比較(row-major opt 和thread pool) ![](https://i.imgur.com/nbdpWeG.png) 好像沒有變快, 為什麼呢? ## 參考資料 * [C fopen vs open](http://stackoverflow.com/questions/1658476/c-fopen-vs-open) * [LanKuDot (李昆憶)共筆](https://hackmd.io/s/HJFhaiAp) ## 待做筆記 * semaphore ###### tags: `ruby` `2016_Autumn` `HW2` `phonebook-concurrent`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully