我正在處理非常長整數(約100,000十進制數字)的乘法運算。作爲我的圖書館的一部分,我添加兩個長號碼。加快x64彙編程序ADD循環
分析顯示我的代碼在add()和sub()例程中的運行時間高達25%,所以重要的是它們儘可能快。但是我看不到太多的潛力。也許你可以給我一些幫助,建議,見解或想法。我會測試他們並回復你。
到目前爲止,我的外接程序做一些設置,然後使用8次展開的循環:
mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
adc rax, r10
mov QWORD PTR [rcx+r11*8-64], rax
7更多塊不同的偏移跟隨,然後循環。
我嘗試加載內存中的值,但沒有幫助。我想這是因爲預取良好。我使用英特爾i7-3770 Ivy Bridge 4核CPU。但我想寫一些適用於任何現代CPU的代碼。
編輯:我做了一些時間安排:它增加了1k字,約2.25個週期/字。如果我移除ADC,那麼只剩下MOV,它仍然需要大約1.95個週期/字。所以主要的瓶頸似乎是內存訪問。庫memcpy()
以大約0.65個週期/字運行,但只有一個輸入,而不是兩個。不過,我猜,由於使用了SSE寄存器,速度要快得多。
一些問題:
- 是否有用使用「負載,負載,加,存儲」結構或將「負載,加入到內存的」幫助?到目前爲止,我的測試沒有顯示出任何優勢。
- 像往常一樣,上證所(2,3,4)沒有幫助可以預計?
- 尋址(縮放索引加基數加偏移)影響嚴重嗎?我可以用
ADD r11, 8
代替。 - 循環展開呢?我讀取展開對桑迪橋架構(Agner Fog http://www.agner.org/optimize/)不利。它是首選還是避免?
- (編輯)我可以使用SSE寄存器從存儲器中加載和存儲更大的塊中的單詞,並有效地與通用寄存器和SSE寄存器交換單詞嗎?
我很欣賞任何意見。
最快的方法(我知道)乘以非常大的數字是一個快速傅立葉變換http://en.wikipedia.org/wiki/Multiplication_algorithm 我從來沒有試圖在彙編中實現它的邏輯。 Appetintly Prime95在x86彙編邏輯中包含了一個快速傅里葉變換,您可以從中自由地(自由地)從這裏獲取 –
謝謝,我知道這一點。現在我只想加快速度。 – cxxl
您可以查看GMP來源。 – zch