sysprog
      • 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
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners 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
    • 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 Help
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
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners 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
    # Linux 核心專題: 井字遊戲改進 > 執行人: Daniel-0224 > [期末專題錄影](https://youtu.be/XbPXcc9R1NA) ### Reviewed by `chloe0919` 能否增加圖表顯示 Fixed point Square root 的實作和浮點數 sqrt 之間的誤差 ### Reviewed by `fennecJ` * 圖片存取權限未正確設定 * 問題一 針對 Fixed point Square root 的實做方法,除了第三周測驗一的方法外,也可使用牛頓法進行,可否針對兩者實做方法進行比較,針對 ttt 的應用場景探討兩個作法的優劣 * 問題二 專題中的定點數採用 Q23.8 的二補數型態,然而本次實做中 mcts 使用到定點數運算的場合應不涉及負數, log 以及開根號也不能針對負數進行運算。是否有機會善用因不會遇到負數而多出來的 1 bit 增加運算精度? * 討論一 我嘗試執行了同學提供於 github 上的 [專案](https://github.com/Daniel-0224/lab0-c) ,commit = e4fceab27 ,卻發生 Segmentation fault 。這邊提供發生 Segmentation fault 時我輸入的命令以便同學重現: ```bash $ git clone git@github.com:Daniel-0224/lab0-c.git $ cd lab0-c $ make $ ./qtest cmd> ttt X> A1 computer move X> A2 computer move X> B3 computer move X> B2 computer move X> B1 cmd> option AI_vs_AI 1 cmd> ttt ... (computer moves) cmd> quit ``` 之後便發生 Segmentation fault ,請找出導致 Segmentation fault 的原因並改善。 ### Reviewed by `yu-hsiennn` 圖片存取權限失敗,以及使用 lab0 規範的程式碼書寫風格,務必用 clang-format 確認一致。 ### Reviewed by `dockyu` 如果想以 Linux Kernel 的標準來撰寫程式,要遵循以下的規範,使用 `\** *\` > The opening comment mark /** is used for kernel-doc comments. The kernel-doc tool will extract comments marked this way. The rest of the comment is formatted like a normal multi-line comment with a column of asterisks on the left side, closing with */ on a line by itself. ### Reviewed by `ChenFuhuangKye` 如何證明歐拉方法的結果幾乎和浮點數 log 相等。 ### Reviewed by `eleanorLYJ` 逼近求近似 裡的公式推導 少一個 ")" ### Reviewed by `randyuncle` 能否精簡的呈現您的程式碼,而非直接張貼所有的程式?並對呈現出來的程式碼做說明? ### Reviewed by `jujuegg` 請問你在電腦 vs 電腦的對弈中會有每次測試的棋譜都一樣的問題嗎,只要第一步下的是一樣的位置,接著後面所有的步驟都會完全相同。 ## 任務簡介 重做[第三次作業](https://hackmd.io/@sysprog/linux2024-ttt),並彙整其他學員的成果。 ## TODO: 以定點數實作 Monte Carlo tree search (MCTS) `MCTS(Monte Carlo Tree Search)` 是一種搜尋樹的算法。它通常應用於決策問題的求解,特別是在棋類等遊戲中。`MCST` 通過隨機模擬和搜尋樹的擴展來評估每個可能的決策,以找到最佳的行動策略。 `MCTS` 在每一次的疊代一共會有 `4` 步,分別為: **Selection :** 在搜尋樹中從根節點開始,根據某種策略選擇下一步要擴展的節點,以找到潛在最佳的行動。 **Expansion :** 對於選擇的節點,擴展子節點,即生成可能的下一步行動或狀態。這些子節點尚未被完全探索,需要進一步評估其價值。 **Simulation :** 對每個擴展的子節點進行模擬或評估。通常使用蒙特卡羅模擬來模擬隨機的遊戲或決策過程,以估計每個子節點的潛在價值或勝率。 **Backpropagation :** 將模擬結果向上反向傳播到搜尋樹的根節點,更新每個節點的統計信息,如訪問次數和累計獎勵。這有助於調整每個節點的價值估計,以改進未來的選擇策略。 透過不斷迭代的選擇、擴展、模擬和反向傳播,`MCTS` 能夠在復雜的決策問題中尋找到較佳的解決方案。 ### 定點數運算: 定點數運算中, [Q notation](https://en.wikipedia.org/wiki/Q_(number_format)) 是一種指定二進制定點數參數的方法。 - Qm.f:例如 Q23.8 表示該數有 23 個整數位、8 個小數位,是 32 位二補數。 假設我們將 fraction bit 設為 $d$,則一定點數 $N$ 的實際值為 $\frac{N}{d}$ 因此當我們在做定點數的加減時可以直接相加。 $(N_1+N_2) \div d = \frac{N_1+N_2}{d}$ $(N_1-N_2) \div d = \frac{N_1-N_2}{d}$ 但是如果對於定點數的乘除不多加處理的話,結果會變為: $(N_1*N_2) \div d = \frac{N_1*N_2}{d}$ $(N_1/N_2) \div d = \frac{N_1/N_2}{d}$ 顯然與預期的結果不同,因此在計算完定點樹的乘除之,需要額外對積數與商數右移或左移 $d$ 位 $\frac{(N_1*N_2)}{d} \div d = \frac{N_1*N_2}{d^2} = \frac{N_1}{d} * \frac{N_2}{d}$ $\frac{(N_1)}{N_2*d} * d = \frac{N_1}{N_2} = \frac{N_1}{d} / \frac{N_2}{d}$ 了解定點數,將 `MCTS` 當中浮點數運算進行以下更動。 首先在 `console.h` 定義 `SCALING_BITS`。 ``` #define SCALING_BITS 8 ``` `calculate_win_value` ,將 `1.0, 0.0, 0.5` 全部更換成自定義定點數的形式。 ```diff Q23_8 calculate_win_value(char win, char player) { if (win == player) - return 1.0; + return 1U << SCALING_BITS; if (win == (player ^ 'O' ^ 'X')) - return 0.0; + return 0U; - return 0.5; + return 1U << (SCALING_BITS - 1); } ``` 另外一處重點變更在於 `uct_score` 的計算函式。 公式如下 $$ \cfrac{w_i}{n_i} + c \sqrt{\cfrac{ln(N_i)}{n_i}} $$ * $w_i$ 代表第 i 次決定後該節點贏的次數 * $n_i$ 代表該節點在第 i 次決定後共做幾次模擬 * $N_i$ 代表該節點的父節點在第 i 次決定後共做幾次模擬 * $c$ 代表 exploration parameter ,通常定為 $\sqrt{2}$ 。 因為在 `EXPLORATION_FACTOR * sqrt(log(n_total) / n_visits)` 這一項, `sqrt()`, `log()` 本身就使用浮點數運算,因此我們要設計對應的定點數運算來取代這兩個函式。 ```c static inline Q23_8 uct_score(int n_total, int n_visits, Q23_8 score) { if (n_visits == 0) return INT32_MAX; Q23_8 result = score << Q / (Q23_8) (n_visits << Q); int64_t tmp = EXPLORATION_FACTOR * fixed_sqrt(fixed_log(n_total) / n_visits); Q23_8 resultN = tmp >> Q; return result + resultN; } ``` ### Fixed point Square root 此處,利用 [第三周測驗一](https://hackmd.io/@sysprog/linux2024-quiz3#%E6%B8%AC%E9%A9%97-3) 的方法實作,並且轉為定點數。 ```c int i_sqrt(int x) { if (x <= 1) return x; int z = 0; for (int m = 1UL << ((31 - __builtin_clz(x)) & ~1UL); m; m >>= 2) { int b = z + m; z >>= 1; if (x >= b) x -= b, z += m; } return z; } ``` ```c Q23_8 fixed_sqrt(Q23_8 x) { if (x <= 1 << Q) return x; Q23_8 z = 0; for (Q23_8 m = 1UL << ((31 - __builtin_clz(x)) & ~1UL); m; m >>= 2) { int b = z + m; z >>= 1; if (x >= b) x -= b, z += m; } z = z << Q / 2; return z; } ``` ### Fixed point log #### 泰勒展開式 嘗試使用泰勒展開實作自然對數的計算,公式如下: $ln(1+x) = x - \frac{x^2}{2} + \frac{x^3}{3} - \frac{x^4}{4} +......$ 以下是我的實作: ```clike Q23_8 fixed_log(Q23_8 x) { Q23_8 fixed_x = x << SCALING_BITS; if (x == 0) return UINT32_MAX; if (x == 1) return 0ULL; Q23_8 result = 0; for (int i = 1; i <= 20; ++i) { if (i % 2 == 0) { result -= fixed_power_int(fixed_x, FIXED_SCALING_BITS, i) / (i << SCALING_BITS); } else { result += fixed_power_int(fixed_x, FIXED_SCALING_BITS, i) / (i << SCALING_BITS); } result = result >> SCALING_BITS; } return result; } ``` 但自己實作時遇到了一些問題,目前還沒解決。 > 因此參考了 `marvin0102` 同學的實作 ```clike Q23_8 fixed_log(int input) { if (!input || input == (1U << Q)) return 0; int64_t y = input << Q; y = ((y - (1U << Q)) << (Q)) / (y + (1U << Q)); int64_t ans = 0U; for (unsigned i = 1; i < 20; i += 2) { int64_t z = (1U << Q); for (int j = 0; j < i; j++) { z *= y; z >>= Q; } z <<= Q; z /= (i << Q); ans += z; } ans <<= 1; return (Q23_8) ans; } ``` ![comp](https://hackmd.io/_uploads/rkBiYJpI0.png) 上圖是我利用同學的方法與浮點數 log 比較,可以從實驗結果發現使用泰勒展開,當數字越大時,誤差越大,且需要越多的項次才能做精準的估算。 #### 逼近求近似 為了改善泰勒展開數字越大時誤差越大的問題,嘗試利用逼近法求 log 的近似值,假設 $A<=x<=B$ ,求其近似值,方法如下: $C = \sqrt{AB}$,因為 $log(C) = log(\sqrt{AB}) = \frac{1}{2}(log(A)+log(B)$,因此我們可以得到 $log(C)$ 為 $log(A)$、$log(B)$ 的平均。 接著比較 $x$ 與 $C$,如果 $x=C$ 及得到我們所求,如果 $x<C$ ,我們則將 $B$ 替換成 $C$ ,如果 $x>C$ ,我們則將 $A$ 替換成 $C$,繼續下一輪的求近似。 因為求近似值時,須先知道 $log(A)$、$log(B)$ 的實際值,因此實作時,將以 $log_2(x)$ 做計算,且 $A$ $B$ 分別為 $2^m$ 及 $2^{m+1}$ ,其中 $2^m<=x<=2^{m+1}$。 ``` A x B ------>---|---<------ ``` 實作如下: ```c Q23_8 fixed_log(int input) { if (!input || input == 1) return 0; Q23_8 y = input << Q; // int to Q15_16 Q23_8 L = 1L << ((31 - __builtin_clz(y))), R = L << 1; Q23_8 Llog = (31 - __builtin_clz(y) - Q) << Q, Rlog = Llog + (1 << Q), log; for (int i = 1; i < 20; i++) { if (y == L) return Llog; else if (y == R) return Rlog; log = fixed_div(Llog + Rlog, 2 << Q); int64_t tmp = ((int64_t) L * (int64_t) R) >> Q; tmp = fixed_sqrt((Q23_8) tmp); if (y >= tmp) { L = tmp; Llog = log; } else { R = tmp; Rlog = log; } } return (Q23_8) log; } ``` ![comp](https://hackmd.io/_uploads/S1mZRkaU0.png) 歐拉方法的結果幾乎和浮點數 log 相等。 ## TODO: 實作「人 vs.電腦」和「電腦 vs. 電腦」的對弈 ### 整合 `linux/list.h` 和 `jserv/ttt` 首先將 `Linux` 核心的 `linux/list.h` 標頭檔與 `hlist` 相關的程式碼抽出,成為 `hlist.h` 整合進 `lab-0`,再將 `jserv/ttt` 專案的程式碼部分整合進 `lab0-c` 。其中包含 `console` ,`game` , `mt19937` , `mcts` , `negamex` 等檔案。 ### 新增 `ttt` 命令 將 `jserv/ttt` 的 `main` 檔案修改整合入 `console.c` ,新增`ADD_COMMMAND` ,修改 `Makefile` 讓程式能夠執行。 ```clike ADD_COMMAND(ttt, "Play Tic-Tac-Toe Game", ""); ``` >commit [95a09bc](https://github.com/Daniel-0224/lab0-c/commit/95a09bc) ### 人 vs.電腦 做完上述方法就能執行 `qtest` 再使用 `do_ttt` 開始玩 `Tic-Tac-Toe`。 ``` tseng@tseng-System-Product-Name:~/linux2024/lab0-c$ ./qtest cmd> ttt 1 | 2 | 3 | 4 | ---+------------- A B C D X> b2 1 | 2 | × ○ 3 | 4 | ---+------------- A B C D ``` ### 電腦 vs.電腦 增加 `option` 指令 `AI_vs_AI`,讓 `AI` 和 `AI` 對弈,使用的演算法是 `negamax`。 ```clike static int ai_vs_ai = 0; else if (ai_vs_ai) { int move = negamax_predict(table, ai).move; if (move != -1) { table[move] = turn; record_move(move); } } ``` 預設值為 `0`,欲更改時需要設定 `AI_vs_AI` 的參數。在 `qtest` 要下的命令是:`option AI_vs_AI 1` 螢幕顯示當下的時間 (含秒數): ```clike static void show_time() { struct timeval currentTime; gettimeofday(&currentTime, NULL); time_t rawtime; time(&rawtime); struct tm *timeinfo = localtime(&rawtime); printf("Current Time: %02d:%02d:%02d:%02ld\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, currentTime.tv_usec / 10000); } ``` 部份結果: ``` tseng@tseng-System-Product-Name:~/linux2024/lab0-c$ ./qtest cmd> option AI_vs_AI 1 cmd> ttt 1 | 2 | × 3 | 4 | ---+------------- A B C D Current Time: 05:28:11:07 1 | 2 | × 3 | 4 | ○ ---+------------- A B C D Current Time: 05:28:11:55 1 | 2 | × 3 | 4 | × ○ ---+------------- A B C D ``` ## TODO: 引入 coroutine 來處理對弈 > 參考 [排程器原理](https://hackmd.io/@sysprog/concurrency/%2F%40sysprog%2Fconcurrency-sched#coroutine-%E5%AF%A6%E4%BD%9C%E9%AB%94%E9%A9%97) > 參考 [coro](https://github.com/sysprog21/concurrent-programs/blob/master/coro/coro.c#L1) > < HenryChaing > 同學 使用 coroutine 的方式實作「電腦 vs 電腦」的對弈模式,其中電腦 A 是使用 negamax 演算法,而電腦 B 是使用 MCTS 演算法。而電腦 A、B 分別對應到 task0 及 task1。至於任務之間的切換,是採用 `setjmp` + `longjmp` 的方法。 #### task ```c struct task { jmp_buf env; struct list_head list; char task_name[10]; char *table; char turn; }; ``` 首先可以看到 `struct task` 有 2 個成員,分別為用於 `setjmp()` 的 `jmp_buf` `env` 以及用於排程的 `list`。第一個成員變數 `env` 即是用來儲存這次進入任務前的程式執行狀態。 ##### setjmp/longjmp 這兩個函式可以轉換程式執行的順序,其中 `setjmp` 可以利用 `jum_buf` 儲存目前程式的狀態,並且在遇到 `longjmp(jum_buf)` 後跳回 `setjmp` 並恢復程式的儲存狀態,這樣的函式設計可以方便程式執行時在不同任務間轉換。 ##### task_add/task_switch 這是主要切換任務的函式,我們用 `list_head` 構成的循環雙向鏈結串列存放即將執行的任務,也就是存放 `jmp_buf` 。其中 `task_add` 可以將任務加到串列當中, `task_switch` 可以切換到我們紀錄的下一個任務執行。 流程設計參照下方程式碼, `schedule` 函式會將兩個任務放到佇列中,而任務執行完的當下會再將這個任務加到佇列當中,若此對局勝負揭曉則不會再將加到佇列當中,佇列為空也就代表並行程式結束執行。 ```c static void task_add(struct task *task) { list_add_tail(&task->list, &tasklist); } static void task_switch() { if (!list_empty(&tasklist)) { struct task *t = list_first_entry(&tasklist, struct task, list); list_del(&t->list); cur_task = t; longjmp(t->env, 1); } } void schedule(void) { static int i; i = 0; setjmp(sched); while (ntasks-- > 0) { struct arg arg = args[i]; tasks[i++](&arg); printf("Never reached\n"); } task_switch(); } ``` ##### task0 , task1 ```c /*negamax*/ void task0(void *arg) { if (setjmp(task->env) == 0) { task_add(task); longjmp(sched, 1); } while (1) { task = cur_task; if (setjmp(task->env) == 0) { char win = check_win(task->table); if (win == 'D') { draw_board(task->table); printf("It is a draw!\n"); break; } draw_board(task->table); int move = negamax_predict(task->table, task->turn).move; if (move != -1) { task->table[move] = task->turn; record_move(move); } task_add(task); task_switch(); } } print_all_moves(); printf("%s: complete\n", task->task_name); longjmp(sched, 1); } /*mcts*/ void task1(void *arg) { if (setjmp(task->env) == 0) { task_add(task); longjmp(sched, 1); } while (1) { task = cur_task; if (setjmp(task->env) == 0) { char win = check_win(task->table); if (win == 'D') { draw_board(task->table); printf("It is a draw!\n"); break; } draw_board(task->table); int move = mcts(task->table, task->turn); if (move != -1) { task->table[move] = task->turn; record_move(move); } task_add(task); task_switch(); } } printf("%s: complete\n", task->task_name); longjmp(sched, 1); } ``` 而 `task0` 和 `task1` 的結構一樣,有三大部份,第一部份根據 `schedule()` 設定的參數決定迴圈次數,將 task 加入排程後呼叫 `longjmp(sched, 1)`,讓 `schedule()` 可繼續將新任務加進排程。當所有任務被加入排程後,`schedule()` 會呼叫 ` task_join(&tasklist)`,其中,會根據 list 的 first entry `longjmp` 回該 task 的 `setjmp` 位置: ```c if (setjmp(task->env) == 0) { task_add(task); longjmp(sched, 1); } ``` 第二部份是兩個 task 交互排程,每次執行一個 loop 後,呼叫 `task_add()` 重新將 task 加入 list 的尾端,並呼叫 `task_switch` 指定 list 的 first task 執行: ```c while(1) { if (setjmp(env) == 0) { task_add(task); task_switch(); } } ``` 第三部份完成該 task,會呼叫 `longjmp(sched, 1)` 跳到 `schedule()`,接著會執行 `task_join(&tasklist)` 執行尚未執行完的 task: ```c printf("Task 1: complete\n"); longjmp(sched, 1); ``` ## TODO: 引入其他快速的 PRNG 實作並比較 MCTS 實作獲得的效益 在 `MCTS` 中,利用 `PRNG` 來產生亂數,以隨機挑選每次模擬中下一步的位置。原本的實作使用 `glibc` 的 `rand()` 函式來產生亂數。以 `4x4` 的棋盤為例,每次最多可能有 `15` 種不同的選項,我用 `0` 到 `14` 來代表這些選項,並使用 `rand()` 進行了一億次的抽樣,接著利用 `perf stat` 執行五次 `ttt` 來測量程式的效能表現,分佈結果如下。 ```c int move = moves[mt19937_rand() % n_moves]; ``` ### rand() ![rand](https://hackmd.io/_uploads/rkdsCi38A.png) ``` Performance counter stats for './qtest': 4091.34 msec task-clock # 0.153 CPUs utilized 40 context-switches # 9.777 /sec 6 cpu-migrations # 1.467 /sec 4,9967 page-faults # 12.213 K/sec 197,2995,5128 cycles # 4.822 GHz 348,7598,8301 instructions # 1.77 insn per cycle 62,0083,0615 branches # 1.516 G/sec 1,4453,6081 branch-misses # 2.33% of all branches 26.799816027 seconds time elapsed 4.045053000 seconds user 0.046658000 seconds sys ``` ### mt19937_rand() ![mt](https://hackmd.io/_uploads/SkRH1n28R.png) ``` Performance counter stats for './qtest': 3850.85 msec task-clock # 0.274 CPUs utilized 27 context-switches # 7.011 /sec 7 cpu-migrations # 1.818 /sec 4,8811 page-faults # 12.675 K/sec 185,1063,2378 cycles # 4.807 GHz 324,6618,8678 instructions # 1.75 insn per cycle 57,2558,3620 branches # 1.487 G/sec 1,4270,6467 branch-misses # 2.49% of all branches 14.057938599 seconds time elapsed 3.811129000 seconds user 0.040032000 seconds sys ``` ### SplitMix64() ![split](https://hackmd.io/_uploads/SyxRk33LC.png) ``` Performance counter stats for './qtest': 3906.89 msec task-clock # 0.178 CPUs utilized 19 context-switches # 4.863 /sec 4 cpu-migrations # 1.024 /sec 4,3332 page-faults # 11.091 K/sec 187,3365,9566 cycles # 4.795 GHz 330,9484,1594 instructions # 1.77 insn per cycle 58,3272,5701 branches # 1.493 G/sec 1,3575,9274 branch-misses # 2.33% of all branches 21.998475802 seconds time elapsed 3.859266000 seconds user 0.048090000 seconds sys ``` ### wyhash() ![wy](https://hackmd.io/_uploads/ByL0y32U0.png) ``` Performance counter stats for './qtest': 3896.78 msec task-clock # 0.360 CPUs utilized 24 context-switches # 6.159 /sec 0 cpu-migrations # 0.000 /sec 4,7946 page-faults # 12.304 K/sec 187,4050,0413 cycles # 4.809 GHz 331,1468,0080 instructions # 1.77 insn per cycle 58,1496,6440 branches # 1.492 G/sec 1,4438,8132 branch-misses # 2.48% of all branches 10.825147098 seconds time elapsed 3.835545000 seconds user 0.061725000 seconds sys ``` 結論: 亂數分佈除了 `mt19937_rand()` 相對平均一些,其他分佈都有較明顯的差異。 雖然每個方法都大約差了0.05 至 0.2秒,和差幾億個 cycle,但是沒有像 `vax-r` 同學的實驗結果差異那麽明顯,目前不確定是否是實驗方法有細節的不同。 ## TODO: 改善定點數 > 改寫 lab0-c 既有的 shannon_entropy.c 和 log2_lshift16.h,採用更有效、準確度 (accuracy) 更高的定點數運算實作,需要有對應的數學統計分析和實際執行的討論。

    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