그래서 내가 글을 썼지.

알고리즘에 따라 정말 알고 쓰면 unaligned 가 더 빠른 경우가 있다고.

어디까지나 선택의 문제라고.


kukyakya ( 라고 쓰고 바보 라고 읽는다 ) 가 땍땍 거리면서 개소리라고 우기더라?

그래서 내기를 했지.


inline assembly 나 intrinsic 은 컴파일러에서 허용하는 표현이지만 C/C++ 이 아니니,

C/C++ 로 memcpy 를 구현해 보라고 했지.

테스트 조건도 명시했어.

출발점 주소와 도착점주소가 모두 unaligned 인 상태. 즉

4 바이트 align 된 포인터인

char* src 와

char* dst 기준으로

memcpy( dst + 3, src + 1, size ); 


kukyakya 가 aligned 로 작성해서 ( 두 포인터 다 정렬된 상태로 이동시켜야 됨 )

C++ unaligned 로 작성한 내 코드 보다 빠르면 내가 틀린거고,

그게 아니면 니가 무식한주제에 다른데서 ㅅㅅㅅ 에게 모욕주고, 갤에까지 퍼와서 모욕준거라고.


이문제는 자기가 스스로 짜 보면 알게돼.

kukyakya는 사전에 해봤다고 우겼지만, intel 이 어떻게 돌아가는지 전혀 몰랐지.

( 그러면서 개기긴 왜 개겨? )


만약 위의 경우에서 ( dst + 1, src + 3 이라든지 dst + 1, src + 2 등 4의 배수가 아닌 다른 조합도 마찬가지지만 )


1. src 의 정렬되기 전 앞부분 짜투리인 3바이트를 먼저 dst + 3 위치에 1 byte 단위로 복사하고 나면,

2. memcpy( dst + 6, src + 4, size - 3 ); 를 해야 되는 셈이지. ( src + 4 는 이제 정렬된거 ) 

3. size - 3 도 4의 배수에 맞추어야 하니까 남은 짜투리를 1 byte 단위로 복사하면 되는거구.


즉, 출발이나 도착 한쪽은 aligned 를 맞출수 있지만 다른쪽은 항상 unaligned 처리를 해야 한다는거야.


그러면 어쩔수 없지, src 에서 2번 읽은걸 dst 에 조합해서 넣어줘야함.

이때 bit shift, bit-wise or, bit-wise and 등을 써줘야 하지.

귀찮게 막~~~ 그걸 저 주소 조합별로 다 구현해야함.

최대한 단순화 시켜도 꽤 복잡해져. -> 그래서 컴파일러가 소스 작성 의도를 파악하기 힘들지.


근데, 아까 말했듯이 unaligned 를 지원하기 위한 가속 명령이 준비되어 있댔지?

만약 내가 unaligned 처리를 하지 않고 걍 한쪽 주소만 손쉽게 맞추고 for문을 돌린다고 하면,

한 줄짜리 for 문으로 표현돼.

그걸 컴파일러는 오호 메모리 복사넹. 하고 해석해서 memcpy 를 태워주든, SSE 로 변환하든 하게 되지.

이건 앞서 다른글에서도 적었지만 컴파일러의 재량이야. 케바케.

저녀석이 자꾸 memcpy 물고 늘어지는데 이건 memcpy 와 별개 문제야.

다른 형태의 알고리즘 코드들도 unaligned 형태로 SIMD 최적화 잘되는 경우가 많아~

굳이 intrinsic 동원 안해도 말야. 약간의 요령만 있으면 C/C++ 로도 충분히 최적화 되게 작성할 수 있다는거지.

컴파일러 비위를 못맞추면 최적화가 안되지만 말야.

내가 한동안 요걸 연구함. ㅋㄷ


특히 VC++ 컴파일러는 이걸 아주 잘 해줌.

당연하지만 VC++ 도 코드가 복잡하면 할수록 ( bitwise 를 섞어서 구현한 aligned 처리 처럼 ) 거의 최적화 해내지 못해.

( 해낸다 하더라도 만약 합성부분이 코드로 표현되지 않는다면, 그게 결국 하드웨어 가속 태우는거라 본질적으로 똑같음.

이걸 저녀석이 전혀 눈치 못채고 있는거고 )


그래서 쿠캬캬가 처음 소스코드를 올리고 그 안에 aligned 와 unaligned 함수를 구현했는데 ( 내 수고를 덜어줌 캬캬 ),

엉뚱한 조건에 제대로된 성능체크도 못해놓고 소설을 장황하게 써 놨지.


내가 그걸 비웃으며 돌려보니, 32비트 release 에서 7배 이상 느리더라. 64비트에서도 4배 정도 느렸음.

debug 모드에선 말할것도 없고. ( 10배이상 )

지가 짠 unaligned 앞에 장렬히 전사.


이 결과는 이미 내가 알고 있던거임. 그래서 미리 조금씩은 언급하고 힌트를 줬음. 아예 알고 낸 문제였지.

물론 난 aligned 의 경우도 7배나 느려지게 구현하지는 않았었지. ㅋㅋ


그리곤 명시적 최적화와 묵시적 최적화에 관한 글에서 intrinsic이나 IPP와 같은 프레임웍/라이브러리 를 사용해서

최적화 하는 경우와 단순히 C++ 로 구현할때 컴파일러의 최적화 가능성에 대한 이야기를 했지.


다시 말하지만 C++ 문법으로 표현된 unaligned 주소에 대한 aligned 변환 처리를

현재 최신버전의 VC++컴파일러가 최적화 못해.

intrinsic으로 넘긴다고 하면 그건 이미 aligned 처리도 아님. 당연히 C++ 도 아니공 ㅋㄷ

( 시작 주소 하나 딸랑 맞춰서 되는 이야기가 아니니까 말야 )


이건 어디까지나 어떤 경우에 어떻게 최적화 되는지 알고 가려서 쓸 문제야.

기초적인 일반론 갖고 덤빌 문제가 아니란거지.


알량한 지식 믿고 졸랭 검색하며 덤볐던 kukyakya 에게 애도를. ( 근데 인간적으로 너무 싸가지 없지 않냐? 너? )


p.s. ㅅㅅㅅ 한테 사과하고 ㅅㅅㅅ가 받아주면 ( ㅅㅅㅅ 는 사과 받아줄 아량 정돈 있는 넘 )

내가 제대로 가르쳐 줌.