contributed by
<eeuserp
>, <ruby0109
>, <Sarahyuhancheng
>, <bobsonlin
>
參考Git 情境劇
git branch "Team20"
git push --set-upstream origin Team20
將一個已存在的 branch 設定成 tracking 遠端的branch。$ git branch
: 察看現在所在的 branch$ git checkout [branch名稱]
: 切換 branch$ git pull
: 看到終端機顯示Already up-to-date.
代表 pull 成功Your local changes to the following files would be overwritten by merge
:typedef intptr_t val_t
改成 typedef char *val_t
改成
MergeList(llist_t *a, llist_t *b)
中更改程式執行時先
$ uniq words.txt | sort -R > input.txt
之後再用./sort [ThrdCount] [InputFile]
因為用sort -R 會有其他問題, 改的指令在下面哦~
Ruby
參考How can I shuffle the lines of a text file on the Unix command line or in a shell script?與
‘-R’
‘–random-sort’
‘–sort=random’
Sort by hashing the input keys and then sorting the hash values. Choose the hash function at random, ensuring that it is free of collisions so that differing keys have differing hash values. This is like a random permutation of the inputs (see shuf invocation), except that keys with the same value sort together.
If multiple random sort fields are specified, the same random hash function is used for all fields. To use different random hash functions for different fields, you can invoke sort more than once.
The choice of hash function is affected by the –random-source option.
sort -R 是先用Hash functon把內容轉成Hash value再去sort, 所以若有一樣的line就會有不均勻的分佈
$ uniq words.txt | sort -R > input.txt
中的unique會把一樣的資料合併成一個, 可是在phonebook很可能會有lastName相同可是其他資料不相同的情況, 因此這樣的作法可能會不符合實際的需求。
shuf 參考Why does the command shuf file > file leave an empty file, but similar commands do not? 較好,
更改指令如下:
cat words.txt | shuf > input.txt
不太知道自動測試是測試亂數分佈均不均勻還是程式執行時間?
Ruby
$ diff 參數 檔案 檔案
$ diff --brief 檔案 檔案
Monitor - 為什麼pthread_cond_wait要unlock mutex
Wait(c,m) c是condition variable ;m是 mutex
1.Atomically
2.當signal發生, 會再自動重新拿回mutex lock
Signal
Broadcast
boss/worker model理解
理解Thread Pool
threads的struct是pthread_t;
task queue的struct則是由funciton和argument組成
再來看執行的流程圖
op5不太理解在等待時threadpool_add時為啥要unlock
eeuserp
我覺得我op6可能寫錯了 我再看一下><
Ruby還好你有問!! 發現自己對於Synchronization Objects根本不太了解。我整理個筆記到上面~
Ruby
以下是我的理解,有錯請指正~
先了解Mergesort的運作方式, 從main.c 的Launch the first task中可以看到包含 cut_func 和我們要排序的list被放入pool給task的queue中。
放入thread pool task queue中的functon
1.llist_t *MergeList(llist_t *a, llist_t *b)
2.llist_t *merge_sort(llist_t *list)
3.void merge(void *data)
4.void cut_func(void *data)
5.static void *task_run(void *data)
1.將兩個已經排序過的 list 做合併排序
2.將一個 list 重複拆解 然後 排序後重新組合
5.thread 從 task queue 挑選 taskeeuserp
主要運作函式有三sarah
max_cut
算式過於冗長,可以用 MIN
macro 取代cut_func
在分左右時,註解寫左邊但傳入的是右半的 list,右邊則傳入左半merge_list()
與 merge_n_sort()
移到 merge_sort.c/h
merge_list()
為 merge_n_sort()
,merge_sort()
為 split_n_merge()
merge_list()
中被 free 掉的 llist_t
,其指標應設為 NULL
,避免被使用reference from lankuDotsarah
前面也有提到refactor,可以合併整理成一區,前後都有一些一樣的策略課程助教
Makefile
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program.
參考How to get more detailed backtrace [duplicate]才知道原來是obtaining backtraces需要用的。因為沒有很了解bracktrace, 去查資料找到老師的Who Call Me?, 用程式找funciton返回位址和依據返回位址查函式名稱。不過在這裡是為了給GNU Debugger(GDB)做backtrace。
附上與此相關的網站連結
1.Logan's Blog
2.你所不知道的C語言:動態連結器篇
給大家參考~ bobsonlin
以下是在理解程式碼的過程中, 發現可以改善的地方並一步步改善。
突然發現這個程式雖然有initial cond, 但只有用到mutex, 也就是當沒有task時, thread會一直耗費CPU的資源。 可以照之前老師在phonebook貼的How to synchronize manager/worker pthreads without a join?來添加monitor
參考threadpool-mbrossard的想法
task_run 加上pthread_cond_wait
發現時間似乎是錯的, 其他人的共筆都是約0.5左右。
回去看程式碼才發現應該要把
clock_gettime(CLOCK_REALTIME, &end);
放在tpool_free(pool);的後面,否則只是紀錄到main thread 的時間而沒有整體的
這張圖片的數據很有意義,請修改其版面配置,使其數據具有可讀性課程助教
好, 已調整~
Ruby
圖片中的數字間距還請你們再調整一下~
另外如果數字還是會打到圖例的話,可以把圖例移至左邊,甚至移到表外也可以喔!
參考連結:http://blog.csdn.net/iemyxie/article/details/41548583
文中set key的部份
課程助教
嗨助教~ 我有調整了一下~ 不過圖例移出去的話數字會擠在一起, 所以我把取的位數變少, 如果像下面這樣呢~?
Ruby如果從原本的右上角移至左上角,就不用減少位數了~
課程助教
好開心ˊˇˋ
原本threads數越高, 時間就會飆漲, 改完之後就完全不會了!!!
原因應該是因為monitor可以讓threads在wait queue中sleep,所以不會耗費到CPU的時間~
merge裡面的data_context lock似乎沒有作用
tqueue_size 在這個程式沒有用到也不需要
在wiki看到上面這段, 本來想說試試看memory barrier做lock free, 可是找不太到有沒有其他人這樣做的
Ruby
lock-freedom還沒有很能體會
參考concurrent-ll怎麼作lock-free
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, …)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, …)
These builtins perform an atomic compare and swap. That is, if the current value of *ptr is oldval, then write newval into *ptr.
The “bool” version returns true if the comparison is successful and newval was written. The “val” version returns the contents of *ptr before the operation.
目標:拿掉tqueue_push和tqueue_pop的lock
首先思考怎拿掉原本的monitor,
原本的task queue架構如下:
一開始想了很多種方式, 還不小心不知道在做什麼把linked list改掉了。
需要barrier signal thread work
在tqueue_pop中要有判斷queue->size, 因為可能在裡面的時候被改變
阿阿…胡思亂想試了好多方法, 後來還是在原本原本的的double linked list加上CAS。只是改了好久好久的code, 可是還是沒有出來QAQQ
現在的error如下:
5293 Thread 2:
5293 Invalid write of size 8
5293 at 0x4015B3: tqueue_push (threadpool.c:108)
5293 by 0x401AD1: merge (main.c:94)
5293 by 0x401C8C: cut_func (main.c:135)
5293 by 0x401D73: task_run (main.c:163)
5293 by 0x4E3F183: start_thread (pthread_create.c:312)
5293 by 0x514F37C: clone (clone.S:111)
5293 Address 0xc98bc88 is 24 bytes inside a block of size 32 free'd
5293 at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
5293 by 0x401D7F: task_run (main.c:164)
5293 by 0x4E3F183: start_thread (pthread_create.c:312)
5293 by 0x514F37C: clone (clone.S:111)
5293
5293 Thread 1:
5293 Invalid read of size 8
5293 at 0x4015F5: tqueue_free (threadpool.c:119)
5293 by 0x4017CB: tpool_free (threadpool.c:151)
5293 by 0x401F40: main (main.c:231)
5293 Address 0xc98bde0 is 16 bytes inside a block of size 32 free'd
5293 at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
5293 by 0x40160B: tqueue_free (threadpool.c:120)
5293 by 0x4017CB: tpool_free (threadpool.c:151)
5293 by 0x401F40: main (main.c:231)
5293
5293 Invalid free() / delete / delete[] / realloc()
5293 at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
5293 by 0x40160B: tqueue_free (threadpool.c:120)
5293 by 0x4017CB: tpool_free (threadpool.c:151)
5293 by 0x401F40: main (main.c:231)
5293 Address 0xc98bdd0 is 0 bytes inside a block of size 32 free'd
5293 at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
5293 by 0x40160B: tqueue_free (threadpool.c:120)
5293 by 0x4017CB: tpool_free (threadpool.c:151)
5293 by 0x401F40: main (main.c:231)
5293
5293
5293 More than 10000000 total errors detected. I'm not reporting any more.
5293 Final error counts will be inaccurate. Go fix your program!
5293 Rerun with –error-limit=no to disable this cutoff. Note
5293 that errors may occur in your program without prior warning from
5293 Valgrind, because errors are no longer being displayed.
詢問老師之後, 發現可以參考之前Toward Concurrency中提到的Hungry Birdlock-free實作的方式
執行的時候有時候會有錯誤, 可是不知道怎麼修改或用什麼工具來看比較好><
跑得時間:
lock free好像沒有快很多
為什麼呢?
我不知道要怎麼看是哪一個lock
mutrace 在記憶體區段錯誤時的資訊:
參考concurrent B+ Tree 裡面亮谷同學有提到atomic operation可能遇到的問題
不同task queue結構對效能的影響:
在pool initialize的時候先給定tqueue的大小
tpool_t 中的count名稱容易混淆, 改成thrdCount
若要用成一個ring, queue要變成一個array,
把tpool和tqueue structure合在一起
用array的index(pool->head和pool->tail)來控制ring的head和tail
structure 改完之後先來看執行時間有沒有什麼變化:
似乎有下降一些些
1.andy19950同學的共筆(參考如何修改成適合phonebook的型式)
2.TempoJiJi同學的共筆(參考設計自動測試)
3.LanKuDot /開發記錄(mergesort-concurrent) / github
4. Logan's Blog
5. 你所不知道的C語言:動態連結器篇
6. kobeyu同學的共筆
7. mingnus同學的共筆
8. eeuserp共筆
2016_Autumn
第20組
Mergesort-Concurrent