Yi Chen
    • 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 New
    • Engagement control
    • Make a copy
    • 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 Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy 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
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 2016q3 Homework2 (phonebook-concurrent) contributed by <`ChenYi`> ###### tags `ChenYi` `sysprog` ## 開發環境 Distribution: Ubuntu 16.04 LTS ``` Architecture: x86_64 CPU 作業模式: 32-bit, 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 每核心執行緒數:2 每通訊端核心數:4 Socket(s): 1 NUMA 節點: 1 供應商識別號: GenuineIntel CPU 家族: 6 型號: 60 Model name: Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz 製程: 3 CPU MHz: 3748.632 CPU max MHz: 3800.0000 CPU min MHz: 800.0000 BogoMIPS: 6784.07 虛擬: VT-x L1d 快取: 32K L1i 快取: 32K L2 快取: 256K L3 快取: 8192K ``` ## 預期目標 * 做好筆記 (上次的自己看都覺得慘不忍睹) >> 幻滅是成長的開始 [name=jserv] * 弄懂concurrency 和 parallelisms 的差別 * 學會使用pthread * 效能分析 之前對於這類東西一直覺得很混淆,學OS的時候也只是考過就忘,這次先嘗試把背景知識補齊再開始動工 >> 這部份一直很弱ˊ~ˋ [name=ChenYi] ## 教材閱讀重點整理 閱讀[冼鏡光的並行計算投影片](http://blog.dcview.com/article.php?a=BTgBYw1qUWIAaQ%3D%3D)與[Toward concurrency](https://hackmd.io/s/H10MXXoT)的一些重點紀錄 #### 一些要搞懂的關鍵字 * 行程(Process) * 一個process中可以有多個thread並行執行 * 不同的process有不同的記憶體空間 * 執行緒(Thread) * 在同個process內的執行緒可以同時共享資源(ex.記憶體,code * 在大多數的狀況下,process由threads所組成 * 若CPU有多個processor,可以做到平行化執行(parallel) * 並行(Concurrency) * 多個問題交由一個processor處理 * 可連續或交錯進行 * 平行(Parallelism) * 同個問題交由多個processor來處理 * 同時並進 * Asynchronous 和 Synchronous用圖解比較好懂 >> 可用 [GraphViz](http://www.graphviz.org/) 製圖,HackMD 有支援。中文示範: [Graphviz - 用指令來畫關係圖吧!](http://www.openfoundry.org/tw/foss-programs/8820-graphviz-) [name=jserv] * Synchronous * ![](https://i.imgur.com/G9cNDcd.png) * 左右分別是synchronous的1 thread || multi-threads * O1, O2 , O3皆為空白時間 * Asynchronous * ![](https://i.imgur.com/GvQJQpm.png) * Conditional Variable * 資料參考 https://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/CV.html * conditional variable事實上是event而不是variable * conditional varialbe有wait和signal的operation * 當一個thread等待有事件發生時,他放入waiting queue中(等待呼叫 ==> wait * 當該thread被呼叫後,會執行signal * signal發生時,monitor會尋找在waiting queue中的其中一個thread來執行 * 若完全沒有的話,這個signal就會被完全忽視掉 * Semaphore(信號標) * 是一個具有counter , waiting list ,和兩個作用signal和wait * counter主要有兩種 * counting * binary * 和conditional variable的差別在conditional variable的signal若沒有人接收是會忽視的,而semaphore若沒有設立處理函式的話,有可能導致thread或是整個程式的中止 * 所以必須在thread pool產生執行緒前就事先指定處理函式。 在[The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software](http://www.gotw.ca/publications/concurrency-ddj.html)一文中指出由於硬體製作商,在時脈,散熱,與功耗上遇到了瓶頸(提高時脈,提高溫度,但散熱能力仍無法有效改善)又因為64bits系統所用的程式基本型態例如pointer size從 4 -> 8 bytes,而導致cache裡能存的資料更少,所以逐漸轉向multi-processor的製作,及加大CPU內部的cache size。撰寫Concurrency與Parallel的程式變成了一種趨勢,而不是單純地靠著硬體設備上的更新,就能使程式跑的更快更有效率。 ##### Functional Programming正好是軟體開發逐漸走向multi-thread的受益者 * 因為Funcitonal Languages不會共享資源(有自己的區塊) * 不需要設鎖就可以確保程式的正確性 * 愈來愈多的程式語言支援部份的functional programming >> 不要打錯字,是 "functional (programming) language",知道重要性後,趕快把 recursion 學好,頭腦體操可以磨練你。 [name=jserv] >> 謝謝提醒 [name=chenyi] #### Thread pool * 紀錄有多少thread可以使用,且有多少工作要做 * 讓各執行緒知道該做什麼工作 於 [Toward Concurrency](https://hackmd.io/EYRgzAbAZgDA7ADgLRQJwIMZICww2JYCCLOAQ2GAQQFMxVUATVIA?view#lock-free-thread-pool) 裡有比較詳細的實作,裏面使用的方法是mutex lock,但mutex的獲取與釋放,對於效能會有一定的影響 所以後面又提出了lock-free的解決方案 >> 問題不在於 branch,而在於同步的成本,你之前參照的文章就提到了。 [name=jserv] >> 喔喔 感謝提醒! [name=chenyi] #### Lock-Free Thread Pool ![](https://hackpad-attachments.s3.amazonaws.com/embedded2016.hackpad.com_VJmq0R0ILi6_p.537916_1459234875775_001.PNG) 上面是一般會使用的thread pool實作方式 以下是lock-free化的thread pool ![](https://hackpad-attachments.s3.amazonaws.com/embedded2016.hackpad.com_VJmq0R0ILi6_p.537916_1459234893887_002.PNG) 一般的thread pool實作方式是使用共用的work queue,以mutex保護,在發現待執行工作數目大於worker thread的情況下,將會利用conditional variable來喚醒等待狀態的worker thread。 不同於一般的作法,lock-free的作法是給予每個worker threads自己的work queue。 對於main-thread放工作和worker thread取工作的衝突採ring-buffer解決 此實作參考 https://github.com/xhjcehust/LFTPool * Ring buffer ![](https://hackpad-attachments.s3.amazonaws.com/embedded2016.hackpad.com_VJmq0R0ILi6_p.537916_1459234911980_003.PNG) 在這個實作裡的任務排程為 * Round-Robin : 一個一個問有沒有空來工作 * Least-Load : 找最閒的那位 * 另外還有做Task migration * 考慮各個worker的load-balancing的話,task的遷移是必須的 * 有兩個function * migrate in - 由main thread分配工作 * migrate out - 存在競爭資源問題 (該worker可能正在做事 * 利用C11裏面就有的atomic機制來處理lock問題 * atomic為同步處理機制,不用像是mutex的東西,便能確保變數間的同步 ## POSIX Threads 資料來自於大家所熟知的 [POSIX Threads Programming](https://computing.llnl.gov/tutorials/pthreads/)上 >> 看了一下這邊好像沒什麼能寫的...上面的教學網站太好用了,man上也幾乎都能解決,暫時不做這邊的筆記[name=chenyi] [Mutexes](https://computing.llnl.gov/tutorials/pthreads/#Mutexes) 試著從他的mutex範例學習(只紀錄重點) (程式碼的部份連上去比較好看清楚mutex相關的部份) ```C pthread_mutex_lock (&mutexsum); dotstr.sum += mysum; pthread_mutex_unlock (&mutexsum); ``` (mutex作用為提供各個執行緒在寫入共享記憶體區段的時候,避免覆(誤)寫的情況出現) 所以在進critical section的時候,要使用pthread_mutex_lock()將寫入鎖住,讓其他執行緒,等待該執行緒寫入完成。 ## 實作部份 記一下要做什麼 * 預計實作一般版的thread pool * 效能測試及畫圖 修正一下main.c的部份 ```C= entry *etmp; pHead = pHead->pNext; for (int i = 0; i < THREAD_NUM; i++) { if (i == 0) { pHead = app[i]->pHead->pNext; dprintf("Connect %d head string %s %p\n", i, app[i]->pHead->pNext->lastName, app[i]->ptr); } else { etmp->pNext = app[i]->pHead->pNext; dprintf("Connect %d head string %s %p\n", i, app[i]->pHead->pNext->lastName, app[i]->ptr); } etmp = app[i]->pLast; dprintf("Connect %d tail string %s %p\n", i, app[i]->pLast->lastName, app[i]->ptr); dprintf("round %d\n", i); } ``` 這邊的pHead = pHead->next的部份是沒意義的(pHead->next在此時為NULL) 然後進去迴圈時的i=0的時候,可以省去做判斷,提出來在外面,大部份for迴圈裏面的都是debug用的樣子,另外沒理解錯的話,i = 0的時候phead的值應該要是 app[0]->pHead 才對,etmp目的應該是為了串接分開來的app,所以回圈裡的etmp->pNext應該要給予的值是app[i]->pHead 刪減過後 ```C= entry *etmp; pHead = app[0]->pHead; etmp = app[0]->pLast; for (int i = 1; i < THREAD_NUM; i++) { etmp->pNext = app[i]->pHead; etmp = app[i]->pLast; } ``` 重整後在試跑一次確認程式正確性 ``` ./phonebook_opt size of entry : 24 bytes execution time of append() : 0.005126 sec execution time of findName() : 0.005588 sec ``` 修正後各thread執行時間 ![](https://i.imgur.com/v1dIqJt.png) 我認為會慢因為原本的方法裏面採的有順序的join (0-1-2-3) ```C for (int i = 0; i < THREAD_NUM; i++) pthread_join(tid[i], NULL); ``` 以上面的4條thread為例,若是2先跑完,他必須等到0和1跑完join完才能join進main thread裡 而當thread數目夠高,各thread完成的順序就不會是0-1-2-3-4....而會是看系統怎麼安排(或者原本有寫thread pool去作管控) 先試試看[吳彥寬的實驗筆記](https://hackmd.io/s/BkN1JNQp)裡提到的用非同步的join > 觀察一下程式碼,可以發現是在各自thread裡做append的動作,最後才做串接,也就是說,整個append的過程應該是沒有critical section的,如果能各自先結束並儲存,不要等待其他thread完成的話,應該能節省不少時間 [name=`chenyi`] > ## Reference * [作業網站](https://hackmd.io/s/rJsgh0na) * [Toward Concurrency](https://hackmd.io/EYRgzAbAZgDA7ADgLRQJwIMZICww2JYCCLOAQ2GAQQFMxVUATVIA?view) * [Process wiki](https://en.wikipedia.org/wiki/Process_(computing)) * [Thread wiki](https://en.wikipedia.org/wiki/Thread_(computing)) * [Asynchronous vs synchronous execution, what does it really mean?](http://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean) * [POSIX Thread Programming](https://computing.llnl.gov/tutorials/pthreads) * [C 的Thread pool筆記](http://swind.code-life.info/posts/c-thread-pool.html) * [Semaphore wiki](https://en.wikipedia.org/wiki/Semaphore_(programming))

    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