2013-07-25 67 views
6

如何將兩個64位整數乘以另一個2個64位整數? 我沒有找到任何可以做到的指令。2個64位整數的SSE乘法

+0

在這種情況下,「兩個64位整數」是什麼意思?你的意思是一對64位整數(一個複數)還是一個128位整數,表示爲一對64位整數? –

+0

我的意思是一個單一的m128i位整數表示爲一對64位整數 –

+1

可能重複[此問題](http://stackoverflow.com/questions/12200698/is-it-possible-to-use-sse-v2然後,生成一個128位寬的整數)。 –

回答

3

您需要使用32位乘法操作來實現您自己的64位乘法例程。雖然這可能不會比使用標量代碼更高效,特別是因爲要進行所有必需的操作,會有很多混亂的向量。

+0

從我的頭頂來看,是不是有一個'pmuldqq'或SSE4中加入了什麼? – hirschhornsalz

+0

SSE4中有一個'pmuldq',它是一個32x32 => 64位乘法,因此您可以將它用作64x64位乘法的構建塊。 –

+0

你知道最好的標量算法嗎(假設你只有32位硬件)?這是我會做的。 (a * b)=(al + ah)*(b1 * bh)= t1 + t2 + t3 + t4其中t1 = al * b1,t2 = al * bh,t3 = ah * bl t4 = ah * bh。每個術語將是一個64位數字。那麼t2和t3將不得不再次分成低和高,最後的數將是(a * b)l = t1 + t2l + t31,(a * b)h = t4 + t2h + t3h + c,其中c是來自(a * b)l的任何進位。這是4次修改,還有7次修改。這是這個地方嗎? –

4

我知道這是一個古老的問題,但我實際上正在尋找這個。由於仍然沒有指令,我用Paulul提到的pmuldq自己實現了64位乘法。這是我想出的

__m128i Multiply64Bit(__m128i a, __m128i b) 
{ 
    auto ax0_ax1_ay0_ay1 = a; 
    auto bx0_bx1_by0_by1 = b; 

    // i means ignored 

    auto ax1_i_ay1_i = _mm_shuffle_epi32(ax0_ax1_ay0_ay1, _MM_SHUFFLE(3, 3, 1, 1)); 
    auto bx1_i_by1_i = _mm_shuffle_epi32(bx0_bx1_by0_by1, _MM_SHUFFLE(3, 3, 1, 1)); 

    auto ax0bx0_ay0by0 = _mm_mul_epi32(ax0_ax1_ay0_ay1, bx0_bx1_by0_by1); 
    auto ax0bx1_ay0by1 = _mm_mul_epi32(ax0_ax1_ay0_ay1, bx1_i_by1_i); 
    auto ax1bx0_ay1by0 = _mm_mul_epi32(ax1_i_ay1_i, bx0_bx1_by0_by1); 

    auto ax0bx1_ay0by1_32 = _mm_slli_epi64(ax0bx1_ay0by1, 32); 
    auto ax1bx0_ay1by0_32 = _mm_slli_epi64(ax1bx0_ay1by0, 32); 

    return _mm_add_epi64(ax0bx0_ay0by0, _mm_add_epi64(ax0bx1_ay0by1_32, ax1bx0_ay1by0_32)); 
} 
+2

您是否對代碼進行了任何基準測試,而不是使用通用寄存器進行基準測試?我對結果很感興趣,因爲我正在做64乘64乘的工作。 – jeteon

+0

我只是做了一些基準測試,它比標量乘法(用cl/O2編譯)還要快。平均約831600000次乘法運算。在我有點強大的i7 5820k上0.37秒。同時,相同的標量乘以平均值1.71。所以它快了4倍,這有點怪異。我想cl很擅長優化超標量指令 – JukesOnYou