2011-06-20 37 views
2

Parameter passing in Visual Studio。請注意如何傳遞__m128類型。這是否意味着不應超過4個__m128參數應按值傳遞。參數在Visual Studio和GCC中傳遞

void good_function(__m128, __m128, __m128, __m128, __m128&); 
void bad_function(__m128, __m128, __m128, __m128, __m128); 

這個規則是否適用於GCC?

謝謝!

編輯:是否有可能bad_function的第五個參數可能未對齊?我讀過的地方只有3個參數傳入寄存器(我猜是Win32,而不是x64)。

+0

爲什麼要那麼糟糕?或者你的意思是慢(相對於什麼)?在創建新接口時,應該完全避免使用太多參數的恕我直言功能。 – RedX

+0

「只有3個參數在寄存器中傳遞」 - 在我見過的許多調用約定中,非靜態成員函數的情況如下:3 integer/pointer args + 1隱含「this」指針arg。但它並不總是那麼簡單 - 浮點數和int /指針參數的組合可能允許您在很多平臺上超越此類... – leander

+0

重新錯位:ABI通常非常嚴格地定義編譯器要遵循的必需對齊。如果您看到數據錯位,通常是您的錯:使用指向更高對齊要求類型的指針指向字節流,例如...就「通過值」傳遞(即使它不是在編譯器端以值爲單位實現),如果事情從寄存器溢出到堆棧,編譯器通常會爲您處理堆棧對齊問題。 – leander

回答

2

鏈接的參數傳遞描述實際上是一個x86_64 Windows ABI(應用程序二進制接口)描述,演示如何將值傳遞給組件級別的函數(即,編譯器如何將C函數調用轉換爲部件)。也就是說,前四個參數將作爲使用x86_64平臺上的寄存器的__m128類型的指針傳遞。由於x86_64平臺與32位couterpart相比有更多的寄存器可供使用,因此這種類型的參數傳遞是爲了加速函數調用,因爲訪問存儲在寄存器中的參數將比訪問存儲在內存中的參數值更快像您通常在32位x86平臺上使用cdecl樣式函數調用一樣看到堆棧。如果超出4個參數,則指向__m128類型的其餘指針將存儲在堆棧中。所以根據參數的數量,沒有「好功能」或「壞功能」。在你的例子中,你的兩個函數都很好,只是第二個例子中,其餘參數必須使用堆棧空間,因爲可用於傳遞值的可用寄存器數量已用完。

這就是說,指向__m128類型的指針如果是自動變量,很可能指向堆棧上分配的地址。因此,無論哪種方式,最有可能使用堆棧空間,要麼存儲指向的變量,要麼在處理大於64位的值和其他聚合類型(如類,聯合,陣列等

至於GCC,因爲你所引用的實際上是一個依賴於平臺的ABI實現(在這種情況下是x86_64 Windows),你會在其他平臺上看到的將會有所不同,儘管對於大多數x86_64操作系統,他們將使用一系列寄存器來傳遞函數調用的第一對參數。因此,GCC實際上將使用與x86_64 Windows上的Visual Studio相同的規則,但在其他平臺上,它將爲這些平臺創建基於x86_64 ABI的不同程序集。

2

參數傳遞由來自系統ABI(應用程序二進制接口)的calling convention定義。哪個ABI正在使用取決於您編譯的目標(OS +硬件平臺)。例如,請參閱* nix使用的AMD64 ABI(大致上,我認爲有幾個小變體)。


您提供的鏈接是關於Microsoft x64調用約定參數傳遞的文章。它指出:

  • __m128總是通過指針傳遞,而不是值
  • 前四個整數或指針在RCX始終被傳遞,RDXR8R9

所以給出任何功能只有__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中,則可以在調試器中使用反彙編窗口。

即使你不完全瞭解正在發生的事情,在引擎蓋下稍稍調整一下總是很好的。你會開始看到模式,並可以提出問題或研究你所看到的。