go 언어에서 구조체를 눌러서 크기를 줄이는 글. 을 번역한 글이다.
대부분 추천하지 않는다. C에서는 잠재적 버그나 보안 홀, 성능상의 이유로 메모리 얼라인이 맞지 않을 경우 더미를 삽입하거나 얼라인을 맞춰서 변수의 순서를 재배열하기도 한다.
현대의 마이크로 아키텍처가 하드웨어 메모리 얼라인을 잘 지원한다고는 하나 아마도(...) 성능저하는 필연이다. 비단 x86이 아닌 현대의 arm도 하드웨어 얼라인은 제공하지만 arm쪽이 성능저하는 더 심할 것이다.
통신에 사용할 때는 더욱 문제가 된다. 바이트 오더링 문제라든가, 스왑함수나 구조체를 다루는 레거시와 신코드의 선언이 눈꼽만큼 달라서 망가질 가능성이 있다. 대부분 컴파일 타임에 잡히긴 하지만 아닐 때도 있다.
방금 아무 자료나 검색해봤다.
영어라서 엉성대충 읽었는데 요점은 정렬하라는 이야기다.
초경량 (코텍스M...등) 시스템, arm-thumb 인터워킹의 경우 구조체를 쥐어 짜야 할 수도 있다. 얼라인을 맞추지 않고 꽉꽉 눌러야 된다. 레거시 통신 규격이 얼라인 없이 바이트 단위로 미세하게 쥐어짜있는 경우 섬세하게 얼라인을 맞춰야 한다. 시리얼 통신이라면 99% 그렇다.
캐시 문제로 들어가면 더욱 골치아파진다. A와 B 영역을 들쭉날쭉 교차하며 초빈번 액세스 하는데, A와 B영역의 경계선이 얼라인이 맞지 않고 걸쳐있다치면, 캐시 힛팅율이 와장창 무너질 수 있다.
멀티쓰레드로 가면 거짓공유 문제가 필연으로 발생한다. 위의 A, B영역 문제가 상존할 때, 두 쓰레드가 각각 접근 A와 B를 따로 접근하는 상황이다. 얼라인이 맞아도 거짓공유가 발생하는 판에 얼라인이 틀어져있으면 거짓공유 문제가 발생활 확률이 비약적으로 증가한다. 이 때는 대충 64바이트 얼라인을 따박따박 맞춰두면 복잡한 고민하지 않아도 성능 저하 방어적 코딩이 된다. 사실은 페이지 캐시의 기본 단위인 4킬로 바운더리도 고려하는 쪽이 좋긴 좋다. 애매하게 4.1킬로 이런 것보다는.
그런데 공유한 글은 json을 다룬다. 그다지 성능과는 관계없을 듯 하다. 이런 경우 이런들 저런들 상관이 없을 것 같다. 경량 시스템이라면 눌러써도 되겠다.
내용 추가 :
생각해보니 컴파일러가 SIMD 관련 최적화를 포기할 가능서이 높겠다. AVX, SIMD, MMX, SSE 최적화가 먹으려면 뭐든 얼라인이 따박따박 먹어야 컴파일러가 제대로 최적화 할 확률이 높을 것이다. 쓰까져있으면 패딩, 마진 연산하다가 세월 다 뽑아먹는다. 비트 카운트이나 제로 클리어링도 마찬가지 아닐까.