利用上述 SIMD within a register (SWAR) 的技巧,我們可改寫為以下 memchr_opt 函式:
測試程式碼:
目標為找尋字串中的第一個 '.'
字元,印出第一個 '.'
之後的字串
輸出結果:
7~13
行,程式主要是透過一次檢查 long
長度的字串長度進行快速的查找long
的長度對齊,利用 UNALIGNED
進行判斷long
的長度進行,而根據不同的電腦架構 long
的長度也會不一樣(佔 8 byte 或 4 byte)long
長度則直接對輸入字串查找即可long
指標,所以將字串的的每 long
長度個字元組合成的待檢查數值,每個字元皆由 8 bits 組成,所以若一次查到 8 個字元,會形成 64 bits 的待檢查數值'.'
DETECT_CHAR
巨集, *
解參考與 mask ( '.'
mask)進行查找,若該片段有找出 '.'
在 DETECT_CHAR
會回傳非 0
值則可跳出迴圈,對該片段進行逐字元的查找asrc++;
若沒找到字元則需要往下一個字串片段遞增,而因為宣告型態為 long
型態在遞增(++
)時為每 long
長度進行length -= LBLOCKSIZE;
字串的長度也隨著每個迴圈進行遞減,也是根據 long
長度,若迴圈都沒找到則 length
會得到負值,在後續的程式碼會回傳 NULL
表示位找到目標字元XXXXX:
^
的方式進行查找,若有相符的字元則在 ^
會得到 0
的結果(歸零律: p ^ p = 0)DETECT_NULL
將 0
的值轉成 80
, 將非 0
值轉成 0
測試:
src++;
是以 char
的長度進行移動,每次移動一個 byte
不同於 long
的移動方式