參數傳遞由來自系統ABI(應用程序二進制接口)的calling convention定義。哪個ABI正在使用取決於您編譯的目標(OS +硬件平臺)。例如,請參閱* nix使用的AMD64 ABI(大致上,我認爲有幾個小變體)。
您提供的鏈接是關於Microsoft x64調用約定參數傳遞的文章。它指出:
__m128
總是通過指針傳遞,而不是值
- 前四個整數或指針在
RCX
始終被傳遞,RDX
,R8
,R9
所以給出任何功能只有__m128
參數,最多四個將作爲寄存器中的指針傳遞,而任何其他寄存器將作爲指針傳遞到堆棧上。正如Jason在另一個答案中所指出的那樣,這些指針將指向堆棧中可能存在的值。
__m128
和__m128 &
(以及__m128 *
)在Microsoft x64調用約定中的成本可能相當 - 它們全都通過指針傳遞。
通過AMD64 ABI閱讀,看起來好像第一8個XMM寄存器(%xmm0
通過%xmm8
)是128個位寬並且將由值採取__m128
。因此,在使用AMD64 ABI的系統上(例如linux上的gcc),前八個參數最終將存放在寄存器中。
在這種情況下,它可能可能通過第9到第15 __m128
args作爲參考/指針是有意義的 - 它們可以使用整數寄存器。這將避免將它們複製到堆棧。
我不確定窗口(如mingw)使用哪個約定gcc。據推測,如果它與其他庫進行交互,它必須使用Microsoft x64約定。
如果你很好奇,不過,我會強烈建議進行一些實驗,看拆卸 - GCC的-S
選項是爲這個偉大的!如果您在Visual Studio中,則可以在調試器中使用反彙編窗口。
即使你不完全瞭解正在發生的事情,在引擎蓋下稍稍調整一下總是很好的。你會開始看到模式,並可以提出問題或研究你所看到的。
爲什麼要那麼糟糕?或者你的意思是慢(相對於什麼)?在創建新接口時,應該完全避免使用太多參數的恕我直言功能。 – RedX
「只有3個參數在寄存器中傳遞」 - 在我見過的許多調用約定中,非靜態成員函數的情況如下:3 integer/pointer args + 1隱含「this」指針arg。但它並不總是那麼簡單 - 浮點數和int /指針參數的組合可能允許您在很多平臺上超越此類... – leander
重新錯位:ABI通常非常嚴格地定義編譯器要遵循的必需對齊。如果您看到數據錯位,通常是您的錯:使用指向更高對齊要求類型的指針指向字節流,例如...就「通過值」傳遞(即使它不是在編譯器端以值爲單位實現),如果事情從寄存器溢出到堆棧,編譯器通常會爲您處理堆棧對齊問題。 – leander