关于__vectorcall的使用

vectorcall 是微软在VS2015中增加的 https://msdn.microsoft.com/zh-cn/library/dn375768.aspx

目的是用来优化浮点向量运算,intel处理器种有很多浮点向量寄存器,传统的调用约定(stdcall  cdecl fastcall thiscall) 都是通过通用寄存器(ecx edx /rcx rdx r8 r9)以及堆栈进行参数传递,所以调用的时候,浮点参数需要从栈获取 例如:


float __stdcall addf0(float a, float b, float c)
{
	return a + b + c;
}


的调用时float c = addf0(1, 2, 3);

	float c = addf0(1, 2, 3);
00076EE0  push        ecx  
00076EE1  movss       xmm0,dword ptr [__real@40400000 (080CDCh)]  
00076EE9  movss       dword ptr [esp],xmm0  
00076EEE  push        ecx  
00076EEF  movss       xmm0,dword ptr [__real@40000000 (080CC8h)]  
00076EF7  movss       dword ptr [esp],xmm0  
00076EFC  push        ecx  
00076EFD  movss       xmm0,dword ptr [__real@3f800000 (080CC4h)]  
00076F05  movss       dword ptr [esp],xmm0  
00076F0A  call        addf0 (0711A4h)  
00076F0F  fstp        dword ptr [c]  

可以看出是通过栈传递的(push ecx 随便压入栈一个数,然后用mov写栈顶)再看看vectorcall

float __vectorcall addf3v(float a, float b, float c)
{
	return a + b + c;
}

调用的汇编代码(可以看出直接通过寄存器传递参数,这样就是比通过栈快)

	float c = addf3v(1, 2, 3);
003AB550  movss       xmm2,dword ptr [__real@40400000 (03B0CDCh)]  
003AB558  movss       xmm1,dword ptr [__real@40000000 (03B0CC8h)]  
003AB560  movss       xmm0,dword ptr [__real@3f800000 (03B0CC4h)]  
003AB568  call        addf3v (03A170Dh)  
003AB56D  movss       dword ptr [c],xmm0  


微软的解释大概是vectorcall 继承于fastcall 但对于fastcall中的整数仍然按照fastcall规则传递 而浮点以及向量将通过寄存器传递

例如

float __vectorcall addvi3f3(int a, float b, int c, float d, int e, float f)
{
	return a + b + c + d + e + f;
}

调用float c = addvi3f3(1, 2, 3, 4, 5, 6);

	float c = addvi3f3(1, 2, 3, 4, 5, 6);
0023B5C0  push        5  
0023B5C2  movss       xmm2,dword ptr [__real@40c00000 (0240CE8h)]  
0023B5CA  movss       xmm1,dword ptr [__real@40800000 (0240CE0h)]  
0023B5D2  mov         edx,3  
0023B5D7  movss       xmm0,dword ptr [__real@40000000 (0240CC8h)]  
0023B5DF  mov         ecx,1  
0023B5E4  call        addvi3f3 (0231712h)  
0023B5E9  movss       dword ptr [c],xmm0 

可以看到 1 3 5 符合fastcall调用 而2 4 6 则通过寄存器传递的,这样vectorcall 比传统调用约定更加快速

































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章