2017-02-26 23 views
1

我想這樣搜索兩個給定值之一的彙編緩衝區,,它僅相差。假設0xfefefeff0xfefefefe(換句話說 - lsb對於搜索無關緊要)在彙編中搜索2個不同值的最快方法

緩衝區的長度會有所不同。

我以爲那個任務大約兩種可能的方式:

方式#1:

mov eax, 0xfefefeff 
test eax, eax 
repne scasd 
... 
mov eax, 0xfefefefe 
test eax, eax 
repne scasd 

方式#2:

mov eax, 0xfefefefe 
lblSearch: 
mov esi, [edi] ; edi - the buffer 
and si, 0fffeh 
cmp eax, esi 
... 
add edi, 4 
loop lblSearch 

我試圖來衡量的執行時間使用QueryPerformanceCountervisual studio diagnostic tools在那__asm片段C,但找不到一致的結果。這個問題的表現非常重要。

任何想法是什麼將是一個更好的方式來實現呢?

謝謝。

+0

這是每個數據樣本兩次比較的最壞情況,這很可能是記憶債券的表現。 – user3528438

+1

你的緩衝區有多大? – Jester

+0

so x86上的操作系統?測量性能將是困難的。你必須和明確地進行比較,所以要麼嘗試在一個事務中執行更大的讀取操作,並且可能會燒錄更多指令或燒錄更少的指令並執行更多的數據訪問。不認爲有一個真正的捷徑。 –

回答

1

在用自己的方式#2 and si,imm16是一個問題,這是部分16B寫入esi再下cmp eax,esi需要回由32B價值,這將導致混亂登記走樣和依賴性。

寧可做and esi,0xfffffffe,它只適用於esi,所以在內部不需要別名/複製/合成。

而且你可能想展開它,特別是如果緩衝區的大小可以被一些不錯的數字整除的話,否則做一些序列來對齊它。

而且不要使用loop,這是人爲的慢。

也取決於你在found/not_found情況下做了什麼,它可能會寫入,而不會在內部循環內部分支(例如計算這些值的數量)。

所以對路#2重寫:

; search for values 0xfefefefe and 0xfefefeff 
    mov eax, 0xfefefefe 
    mov edx, 0xfffffffe 
    ; edi = buffer 
    ; ecx = number of elements in buffer 
lblSearch: 
    mov esi, [edi] ; edi - the buffer 
    add edi, 4 
    and esi, edx 
    cmp esi, eax 
    jne lblNotFound 
    ... one of values found 
lblNotFound: 
    dec ecx 
    jnz lblSearch 

這絕不意味着它推到了極限,爲你沒有披露足夠的信息。如果性能非常重要,則可能需要展開此等等。

甚至檢查整個體系結構以查看是否可以在生產者中捕獲此類值,而無需任何搜索。

這比您的「途徑2」要快得多,僅此而已。

相關問題