簡體   English   中英

使用SSE將4個浮點數乘以4個浮點數的最有效方法是什么?

[英]What's the most efficient way to multiply 4 floats by 4 floats using SSE?

我目前有以下代碼:

float a[4] = { 10, 20, 30, 40 };
float b[4] = { 0.1, 0.1, 0.1, 0.1 };
asm volatile("movups (%0), %%xmm0\n\t"
             "mulps (%1), %%xmm0\n\t"             
             "movups %%xmm0, (%1)"             
             :: "r" (a), "r" (b));

我首先要問幾個問題:

(1)如果我要在16字節邊界上對齊數組,它甚至可以工作嗎? 由於數組是在堆棧上分配的,因此對齊它們幾乎是不可能的嗎?

看到這篇文章的選定答案: 堆棧變量是否由GCC __attribute __((aligned(x)))對齊?

(2)代碼是否可以重構以提高效率? 如果我將兩個浮點數組都放在寄存器而不只是一個?

謝謝

用C寫,用

gcc -S -mssse3

如果你有一個相當新版本的gcc。

GCC是否支持__m128數據類型? 如果是這樣,那是保證16字節對齊數據類型的最佳計划。 盡管如此,還是有__attribute__((aligned(16)))來對齊事物。 按如下方式定義數組

float a[4] __attribute__((aligned(16))) = { 10, 20, 30, 40 };
float b[4] __attribute__((aligned(16))) = { 0.1, 0.1, 0.1, 0.1 };

然后使用movaps而不是:)

如果我想在16字節邊界上對齊數組,它甚至可以工作嗎? 由於數組是在堆棧上分配的,因此對齊它們幾乎是不可能的嗎?

要求堆棧上的對齊有效。 否則內在函數不起作用。 我猜你引用的帖子與他為對齊值選擇的過高價值有關。

到2:

不,性能不應該有差異。 有關多個處理器的指令時序,請參閱此站點


堆棧變量的對齊方式如何工作:

push    ebp
mov ebp, esp
and esp, -16                ; fffffff0H
sub esp, 200                ; 000000c8H

並將堆棧的開頭與16字節對齊。

(1)如果我想在16字節邊界上對齊數組,它甚至可以工作嗎? 由於數組是在堆棧上分配的,因此對齊它們幾乎是不可能的嗎?

不,使用and對齊堆棧指針非常簡單:

and esp, 0xFFFFFFF0 ; aligned on a 16-byte boundary

但是你應該使用GCC提供的內容,例如16字節類型或__attribute__來自定義對齊。

使用內在更快,特別是在優化時。 我寫了簡單的測試並比較兩個版本(asm和內在)

unsigned long long time1;
__m128 a1,b1;


a1=_mm_set_ps(10, 20,30,40);
b1=_mm_set_ps(0.1, 0.1, 0.1, 0.1);
float a[4] = { 10, 20, 30, 40 };
float b[4] = { 0.1, 0.1, 0.1, 0.1 };

time1=__rdtsc();
a1=_mm_mul_ps(a1,b1);
time1=__rdtsc() - time1 ;
printf("Time: %llu\n",time1);


time1=__rdtsc();
asm volatile("movups (%0), %%xmm0\n\t"
                 "mulps (%1), %%xmm0\n\t"
                 "movups %%xmm0, (%1)"
                 :: "r" (a), "r" (b));
time1=__rdtsc() - time1 ;
printf("Time: %llu\n",time1);

內部版本50-60處理器時間戳Asm Version~1000 proc時間戳

您可以在您的機器上進行測試

關於重構。 你可以使用內在的。 例:

#include <emmintrin.h>

int main(void)
{
    __m128 a1,b1;

    a1=_mm_set_ps(10, 20,30,40);
    b1=_mm_set_ps(0.1, 0.1, 0.1, 0.1);

    a1=_mm_mul_ps(a1,b1);

    return 0;
}

使用優化gcc( -O2-O3 ),它可能比asm工作得更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM