2013-07-25 7 views
6

दो 64-बिट पूर्णांक को दो 64-बिट पूर्णांक से गुणा कैसे करें? मुझे कोई निर्देश नहीं मिला जो इसे कर सकता है।एसएसई गुणा 2 64-बिट पूर्णांक

+0

इस संदर्भ में "दो 64 बिट पूर्णांक" का क्या अर्थ है? क्या आपका मतलब 64 बिट पूर्णांक (एक ला जटिल संख्या) की एक जोड़ी है, या एक 128 बिट पूर्णांक 64 बिट पूर्णांक की एक जोड़ी के रूप में दर्शाया गया है? –

+0

मेरा मतलब है कि एक बिट एम 128i बिट इंटीजर 64 बिट पूर्णांक की एक जोड़ी के रूप में दर्शाया गया है –

+1

[इस प्रश्न] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/12200698/is-it-possible-to-use-sse-v2 -to-make-a-128-bit-wide-integer), फिर। –

उत्तर

3

आपको 32 बिट गुणा संचालन का उपयोग करके अपने 64 बिट गुणात्मक दिनचर्या को लागू करने की आवश्यकता होगी। यह शायद स्केलर कोड के साथ ऐसा करने से कहीं अधिक कुशल नहीं होगा, विशेष रूप से क्योंकि सभी आवश्यक संचालन प्राप्त करने के लिए वैक्टरों में बहुत सारे शफल होंगे।

+0

मेरे सिर के शीर्ष से, क्या कोई 'pmuldqq' नहीं था या एसएसई 4 में कुछ जोड़ा गया था? – hirschhornsalz

+0

एसएसई 4 में एक 'pmuldq' है जो 32x32 => 64 बिट गुणा है, इसलिए आप इसे 64x64 बिट गुणा करने के लिए बिल्डिंग ब्लॉक के रूप में उपयोग कर सकते हैं। –

+0

क्या आप इस के लिए सबसे अच्छा स्केलर एल्गोरिदम जानते हैं (मानते हैं कि आपके पास केवल 32-बिट हार्डवेयर है)? क्या यही मुझे करना होगा। मैं प्रत्येक नंबर को अपने ऊपरी और निचले 32-बिट भाग में विभाजित करता हूं और फिर (ए * बी) = (अल + एएच) * (बीएल * बीएच) = टी 1 + टी 2 + टी 3 + टी 4 जहां टी 1 = एल * बीएल, टी 2 = अल * बीएच, टी 3 = आह * बीएल टी 4 = आह * बीएच। प्रत्येक शब्द 64-बिट संख्या होगी। फिर टी 2 और टी 3 को फिर से कम और उच्च में विभाजित करना होगा और अंतिम संख्या (ए * बी) एल = टी 1 + टी 2 एल + टी 3 एल, (ए * बी) एच = टी 4 + टी 2 एच + टी 3 एच + सी, जहां सी किसी भी वाहक (ए * बी) एल है। यह 4 mults है, और 7 जोड़ता है। क्या यह कहीं SO पर है? –

4

मुझे पता है कि यह एक पुराना सवाल है लेकिन मैं वास्तव में वास्तव में इसकी तलाश कर रहा था। चूंकि अभी भी इसके लिए कोई निर्देश नहीं है, मैंने पॉल बिट का उल्लेख करते हुए 64 बिट को pmuldq के साथ गुणा कर दिया। यह मैं

__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

मैंने अभी कुछ बेंचमार्किंग किया है, यह अभी भी स्केलर गुणा (क्लाउड/ओ 2 के साथ संकलित) से तेज है। औसत में लगभग 831600000 गुणा। मेरे कुछ हद तक शक्तिशाली i7 5820k पर 0.37 सेकेंड। इस बीच उसी स्केलर गुणाओं ने औसत पर 1.71 लिया। तो यह लगभग 4 गुना तेजी से है, जो थोड़ा अजीब है। मुझे लगता है कि सीएल सुपरस्कायर निर्देशों को अनुकूलित करने में वाकई अच्छा है – JukesOnYou

संबंधित मुद्दे