# 2025q1 Homework5 (assessment) contributed by < [`h0w726`](https://github.com/h0w726) > ## 從前 6 週的測驗題選出 3 題改進 ### [Week 3 測驗2](https://hackmd.io/@sysprog/linux2025-quiz3#%E6%B8%AC%E9%A9%97-2) #### Linux 核心原始程式碼找出 x86_64 或 arm64 對應的最佳化實作,跟上述程式碼比較,並嘗試舉出其中的策略和分析 在 [linux/arch/arm64/lib/memchr.S](https://github.com/torvalds/linux/blob/master/arch/arm64/lib/memchr.S) 找到在 Linux 核心原始程式碼找出 arm64 對應的最佳化實作如下 ```c /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2021 Arm Ltd. */ #include <linux/linkage.h> #include <asm/assembler.h> /* * Find a character in an area of memory. * * Parameters: * x0 - buf * x1 - c * x2 - n * Returns: * x0 - address of first occurrence of 'c' or 0 */ #define L(label) .L ## label #define REP8_01 0x0101010101010101 #define REP8_7f 0x7f7f7f7f7f7f7f7f #define srcin x0 #define chrin w1 #define cntin x2 #define result x0 #define wordcnt x3 #define rep01 x4 #define repchr x5 #define cur_word x6 #define cur_byte w6 #define tmp x7 #define tmp2 x8 .p2align 4 nop SYM_FUNC_START(__pi_memchr) and chrin, chrin, #0xff lsr wordcnt, cntin, #3 cbz wordcnt, L(byte_loop) mov rep01, #REP8_01 mul repchr, x1, rep01 and cntin, cntin, #7 L(word_loop): ldr cur_word, [srcin], #8 sub wordcnt, wordcnt, #1 eor cur_word, cur_word, repchr sub tmp, cur_word, rep01 orr tmp2, cur_word, #REP8_7f bics tmp, tmp, tmp2 b.ne L(found_word) cbnz wordcnt, L(word_loop) L(byte_loop): cbz cntin, L(not_found) ldrb cur_byte, [srcin], #1 sub cntin, cntin, #1 cmp cur_byte, chrin b.ne L(byte_loop) sub srcin, srcin, #1 ret L(found_word): CPU_LE( rev tmp, tmp) clz tmp, tmp sub tmp, tmp, #64 add result, srcin, tmp, asr #3 ret L(not_found): mov result, #0 ret SYM_FUNC_END(__pi_memchr) SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr) EXPORT_SYMBOL_NOKASAN(memchr) ``` 其中 `chrin` 為所要找的目標字元,`wordcnt` 是將整塊搜尋的記憶體切成幾個 word,`repchr` 與測驗中的 `mask` 用途一樣,產生一段 word 大小的目標字元,`cntin` 表示不足一個 word 長度 (8 bytes) 的部分。 `word loop` 一次搜尋一個 word 裡有沒有目標字元,一樣透過與 `repchr` XOR,若為目標字元,byte 會變為 `0x00`。 其中 ``` sub tmp, cur_word, rep01 orr tmp2, cur_word, #REP8_7f bics tmp, tmp, tmp2 ``` 其實就是測驗中的 `DETECT_NULL`,`orr tmp2, cur_word, #REP8_7f` 對應到 ` x | 0x7f7f7f7f7f7f7f7f`, `bics tmp, tmp, tmp2` 為 `((X) - (0x0101010101010101)) & ~((X)|(0x7f7f7f7f7f7f7f7f))`,因為 `~(A|B) == (~A) & (~B)`,所以這式子和測驗中是等價的,[bics](https://www.scs.stanford.edu/~zyedidia/arm64/bics.html) 會根據 `tmp` 的值更新 flags,如果 zero flags 不等於 0 代表有找到目標字元。 ## 紀錄閱讀〈[因為自動飲料機而延畢的那一年](https://www.opasschang.com/docs/the-story-of-auto-beverage-machine-1)〉的啟發 閱讀這篇文章時,會讓人不自覺地想讀下去,就像許多故事一樣,主角與一群志同道合的朋友想要做一些大事,與很多人不一樣的是,他們是真的投入其中且真的達成了。當然其中也會遇到很多挫折,也會有想放棄的時候,例如主角曾經一度就想說是不是選錯專案,覺得自己是不是在浪費時間,但正如老師所說的 > 你最大的問題在太害怕失敗了,既然都已經決定要延畢做飲料機了,那就要好好做,才不會辜負當初自己的期望。你可以計算要花多少錢,然後評估自己可以接受多少損失,畢業後慢慢還都好,要錢我也可以借你。但青春很貴,你也知道實習會發生什麼事,公司不會指派重要的工作給你,他們只會指派低風險的工作,你學習到的東西並不會比你現在多。你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。 已經決定要做一件事,那就把它做到最好,老師也提到 > 但我相信這個問題絕對不會沒有人碰過,一定有人解決過,所以你不該卡在這裡,因為這件事卡在這裡是相當不值得的。 既然已經有人解決過的問題,那為什麼我沒有能力解決呢,老師上課最常說的「缺什麼補什麼」,遇到問題不懂的,不是去選擇逃避,而是去補充知識,去解決它。工程師不是只需要會打 code ,就像主角一樣,機械領域不熟那就嘗試去學。失敗不可恥,沒辦法承受失敗並進步才可恥。 ## 簡述想投入的專案 1. 在寫 [第一份作業](https://hackmd.io/8LcvFQ-gToaGZAXKYQcZ9g#%E4%BA%82%E6%95%B8) 時,有一個部分是要實作 Xorshift 產生亂數並轉換成字串,當時有參閱 [Linux 核心專題: 亂數產生器研究](https://hackmd.io/@sysprog/BkhlALt8A),了解 Linux 核心中如何產生亂數,亂數在安全上是非常重要的部分,若產生的亂數不夠亂,就有可能被攻擊者利用,想探討 Linux 核心中產生亂數的策略,以及是否有能改進的部分。 2. 完成第三次作業。