Lyn
조회 수 5409 추천 수 0 댓글 0
Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

예전 x86 시절에는 다양한 calling convention 이 있었습니다.

MS가 OS API 의 디폴트로 사용한 pascal 식 호출방식(__stdcall) 막상 언어로 파스칼을 쓰는 델파이가 파스칼식을 사용 하지 않고 사용하고 있던 fastcall, 그리고 c에서 사용하는 cdecl

 

이 각각의 호출 방식은 각각 장단점이 있었는데, pascal 식은 바이너리의 크기가 작아진다, fastcall 은 인자 전달에 레지스터를 사용 하므로 속도에 유리하다, cdecl 은 최적화 단계에서 스택 push ,pop 을 생략할 수 있으므로, 최적화에 유리하고 가변인지를 지원 할 수 있다는 장점이 있었습니다.

 

그러나 바야흐로 x64 시대, 컴파일러를 설계하는 사람들은 각각의 장점을 통합한 새로운 호출 방식을 만들게 되었습니다. 그 이후 calling convention 을 지정하는 모든 키워드는 x64 컴파일시에 무시되며, 그런거 신경 안써도 되는 평화로운 세월이 이어져 왔습니다.

 

그러나 시간이 흘러 CPU는 클럭경쟁의 시대가 막이 내리고, SMID 와 멀티코어의 시대로 넘어 왔는데... 당연히 CPU 제조사들은 새 SIMD 명령어를 추가 하기 시작 했고, 그에 맞춰 새 명령어용 레지스터가 추가 되었습니다. 그 시점에서 컴파일러 개발자들은 이렇게 생각 햇나 봅니다 "어? 레지스터가 놀고있네?" 라고. 그리하여 VS2013 이후부터는 __vectorcall 이라는 키워드가 추가되어, 더이상 x64 바이너리에서도 calling convention 을 무시 할 수 없게 되었습니다.

 

간단한 예제를 보겠습니다.

 

#include <cstdio>
#include <intrin.h>

__m256i func(double d1, double d2, double d3, double d4, __m256i f)
{
    printf("%f %f %f %f\n", d1, d2, d3, d4);

    printf("%lld %lld %lld %lld\n", 
        f.m256i_u64[0], f.m256i_u64[1], f.m256i_u64[2], f.m256i_u64[3]);

    return f;
}

int __cdecl main()
{
    __m256i f;

    for (int i = 0; i < 4; ++i)
    {
        f.m256i_u64[i] = i;
    }
    
    f = func(0.1, 0.2, 0.3, 0.4, f);

    return 0;
}

 

이코드를 빌드해서 실행 해 보면 다음과 같은 코드를 볼 수 있습니다.

vc1.PNG

 

 

그리고 함수의 프로토타입에 __vectorcall 을 추가하여

__m256i __vectorcall func(double d1, double d2, double d3, double d4, __m256i f)

와 같이 만든 후 다시 빌드 해 보겠습니다

 

 

 

vc2.PNG

 

차이가 보이시나요? 첫 줄에서 ymm4 라는 avx 레지스터가 추가적으로 함수 전달에 쓰이는 것을 볼 수 있습니다.
매번 __vectorcall 을 붙이기 싫다면 

vc3.PNG

 

옵션에서 조정 하거나, /Gv 플래그를 추가하여 사용 할 수도 있습니다.
단 /Gv 플래그를 켤 경우, main 은 항상 __cdecl 이어야 한다는 조건이 있으므로, 위 코드처럼 __cdecl 을 붙여주지 않으면 경고가 발생 할 것이니 조심하세요.

TAG •
?

List of Articles
번호 제목 글쓴이 날짜 조회 수
114 사이트에 SSL 인증서를 적용 했습니다... 적용 방법 Lyn 2016.09.07 2062
113 add "open as administrator" menu for gnome file explorer(nautilus) file Lyn 2016.06.25 4362
112 Visual C++ C4503 Warning Fix Lyn 2016.06.21 4744
» New Calling Convention for AMD64(=EM64T, x64) and IA32(=x86) file Lyn 2016.04.17 5409
110 What is the calling convention of the C++ lambda file Lyn 2016.04.11 5347
109 Nuget error after Visual Studio 2015 Update 2 install file Lyn 2016.04.04 5419
108 Geforce 364.72 Vulkan Support file Lyn 2016.03.31 4063
107 [연속기획UD] 3. OpenVPN GUI Client file Lyn 2016.03.14 4761
106 How to Windows Disk Drive Performance Counter On Lyn 2016.03.12 3251
105 [연속기획UD] 2. NAVER Font Installer file Lyn 2016.03.06 4673
104 [연속기획UD] 1. Windows Service Manager file Lyn 2016.03.06 4332
103 [연속기획UD] 윈도우 Desktop Application 의 Unicode, High DPI 를 신경씁시다 Lyn 2016.03.06 4294
102 Windows 10 network priority change file Lyn 2016.02.16 2813
101 VMWare 12 + Windows 10 Bug file Lyn 2016.01.03 3180
100 C++11 Type Traits. 라이브러리가 프로그래머의 제어에서 벗어나다 1 file Lyn 2015.12.30 4604
99 Safe scanf 계열 함수의 함정. 자나깨나 크기조심 secret Lyn 2015.11.17 113
98 OpenVPN이 2.3.8 으로 업데이트 되면서 이것저것 바뀌었는데... 1 Lyn 2015.09.08 2610
97 Disable Windows 10 Device Driver Automatic Update Lyn 2015.08.25 2318
96 만약 사정상 Windows 10 자동 업데이트를 꺼야 한다면 설치해야 할 패치 Lyn 2015.07.22 2377
95 잠시후 한국시각 21일 0시부터 VS 2015 런칭행사를 합니다. Lyn 2015.07.21 2255
Board Pagination Prev 1 ... 2 3 4 5 6 7 ... 8 Next
/ 8