bool은 자료형이 뭘까?
1bit?
아니다.
cpu에서 다루는 최소단위는 1byte이고,
1byte를 쪼개서 1bit로 쓸 순 있지만, 쪼개거나 나누는데 추가 연산이 들어가서 느리다.
그러면 int?
반은 맞다.
CPU를 설계할 때, 제한된 트렌지스터로 설계해야 하는데,
char, int, long long, float 전부 골고루 트렌지스터를 분배하긴 힘들다.
그래서 제일 많이 쓰이는 int에 트렌지스터를 집중한다.
그래서 int가 맞는거죠?
임베디드 시스템에서는 int가 bool이 맞을것이다.
하지만 위의 내용은 x86_64(intel)같은 우리가 쓰는 아키텍쳐에 적용되지는 않는다.
왜냐하면 임베디드와 달리 트렌지스터와 집적도가 충분해서 설계시 자료형마다 고루고루 분배할 수 있기 때문이다.
그래서 char, short, int, long long 모두 속도가 똑같다. (Latency 기준, 대부분 경우)
Copyright (C) 1995-2017 FinalWire Ltd. All rights reserved
Intel i7-8700k Instruction Latency
70 X86 : ADD r8, r8 L : 0.27ns = 1.0c T : 0.06ns = 0.24c
71 X86 : ADD r16, r16 L : 0.27ns = 1.0c T : 0.08ns = 0.31c
72 X86 : ADD r32, r32 L : 0.27ns = 1.0c T : 0.06ns = 0.22c
73 AMD64 : ADD r64, r64 L : 0.27ns = 1.0c T : 0.08ns = 0.31c
74 X86 : ADD r8, [m8] L : 1.62ns = 6.0c T : 0.14ns = 0.50c
75 X86 : ADD r16, [m16] L : 1.62ns = 6.0c T : 0.14ns = 0.50c
76 X86 : ADD r32, [m32] L : 1.62ns = 6.0c T : 0.14ns = 0.50c
77 AMD64 : ADD r64, [m64] L : 1.62ns = 6.0c T : 0.14ns = 0.50c
C
복사
그러면 우리가 쓰는 bool 은 뭔데요;;;
2000년 초를 기점으로 CPU클럭 향상이 한계에 도달하고,
멀티코어, 캐시메모리, out-of-order, SMT(hyper thread) 같은 부분들이 발전하고 있다.
그 중 여기서 중요한건 캐시메모리이다.
char, short, int, long long 모두 연산하는 속도가 같다면,
연산하기 위해 메모리에 load, store하는 비용이 적은 것을 선택해야 한다.
캐시 메모리는 작기 때문에, 큰 데이터를 많이 사용하면 Cache-Miss(내가 원하는 데이터가 캐시에 없음) 이 자주 발생한다.
결론
그래서 우리가 쓰는 bool은, 제일 크기가 작은 char를 사용한다.
연산속도가 다른자료형과 같고, load-store 할 때, Cache-Hit 할 확률이 높으므로 빠르다.
Memory Alignment를 신경쓰지 않아도 된다는 것도 장점이다.
여담
물론 Latency가 아닌 Throughput은 r32가 더 빠를 가능성이 높다. 이건 별개의 문제.
(사실 Throughput이 뭔지 잘 모르겠다. 사람마다 하는 말이 다름…
아마 execution이 끝나고 forward operand로 reservation station에 보내는 시간이던지,
다음 연산이 execution에 들어오기 까지 걸리는 시간 둘 중 하나 같은데..)
컴파일러가 bool을 char로 쓰는 것은 절대적으로 빠르기 때문이 아니라,
일반적인 경우에서 대체적으로 빠르기 때문이다.
그래서 특정 작업에 한해서는 이는 역전될 수 있다.
m1, 임베디드, 콘솔 등에서 작업 시, 혹은 중요한 최적화가 필요할 때에는
instruction 별 Latency와 Throughput를 뽑아놓은 성능표를 보고 고려해야한다.