首頁 >後端開發 >Golang >SSE 指令和彙編優化如何提高具有兩級循環的總體計數演算法的效能?

SSE 指令和彙編優化如何提高具有兩級循環的總體計數演算法的效能?

Linda Hamilton
Linda Hamilton原創
2024-10-26 00:17:281054瀏覽

 How can SSE instructions and assembly optimization improve the performance of a population count algorithm with a two-level loop?

理解問題

在您的程式碼中,您在兩級循環中處理人口計數,並嘗試使用彙編來優化內部循環。此循環迭代位元組切片,並使用 __mm_add_epi32_inplace_purego 函數將位置 popcount 加入陣列。

透過彙編進行最佳化

要最佳化內部循環,您可以在彙編中實現 __mm_add_epi32_inplace_purego。以下是函數的建議最佳化版本:

<code class="assembly">.text
.globl __mm_add_epi32_inplace_purego
__mm_add_epi32_inplace_purego:
    movq rdi, [rsi]
    movq rsi, [rdi+8]
    addq rsi, rdi
    movups (%rsi, %rax, 8), %xmm0
    addq , %rsi
    movups (%rsi, %rax, 8), %xmm1
    paddusbd %xmm0, %xmm0
    paddusbd %xmm1, %xmm1
    vextracti128 <pre class="brush:php;toolbar:false"><code class="assembly">.text
.globl __optimized_population_count_loop
__optimized_population_count_loop:
    movq rdi, [rsi]
    leaq (0, %rdi, 4), %rdx  # multiple rdi by 4, rdx = counts
    movq rsp, r11
    and rsp, -16
    subq r15, r11
    movq r15, r9
    mov rdi, (%rsi)
    movq r15, rsi
    mov %rsi, rsi
    pxor %eax, %eax
    dec %rsi

.loop:
    inc %rsi
    addq , rsi
    cmp rsi, rdi
    cmovge %rsi, rsi
    movsw (%rdi, %rax, 2), %ax
    movsw (%rsi, %rax, 2), %dx
    movw %ax, (%rdx)
    movw %dx, 2(%rdx)

.end_loop:</code>
, %xmm0, %eax vextracti128 , %xmm1, %edx addl %eax, (%rdi) addl %edx, 4(%rdi) addl %r8d, (%rdi) ret

說明:

此組譯程式碼使用打包的 SSE 指令最佳化此函數。它:

  • 使用 paddusbd 計算 16 位元區塊中的 popcount。
  • 使用 vextracti128 提取低 128 位元部分。
  • 將結果加到 [8 ]int32 陣列位於 %rdi 給出的位址處。

使用彙編增強整個循環

解釋:

完整的循環現在在彙編中進行了優化。它使用:

  • 處理 2 位元組區塊的循環。
  • 透過連續的 addq $32、rsi 進行串流加載,以避免快取未命中。
  • 快速而緊湊的使用 movw 保存結果的方法。

結論

這個最佳化版本應該會顯著提高計算位置人口計數演算法的效能。

以上是SSE 指令和彙編優化如何提高具有兩級循環的總體計數演算法的效能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn