glibc/string/strlen.c at 895ef79e04a953cac1493863bcae29ad85657ee1 · lattera/glibc
GitHub
표준 라이브러리의 GLIBC 구현을 보면
himagic = 0x80808080L;
lomagic = 0x01010101L;
....
if (((longword - lomagic) & ~longword & himagic) != 0)
이와 같은 연산이 눈에 보입니다.
사실 이 연산은 무척 매력적인 연산입니다.
저는 가끔 아주 쓸모 없는 프로그램을 짜곤 합니다. 그 중에 하나가 개인적인 문자열 함수를 만드는 것이기도 했지요. 그런데, 제가 짠 문자열 함수는 GLIBC 의 구현의 속도를 따라갈 수 없었답니다. 사실 문자열 처리 함수가 쉬울 것이라고 접근한 저의 미숙함이 큰 것이겠지요. 현재의 strlen 구현이 있기 까지, 많은 노고가 들어가 있답니다. 현재는 SIMD(Single Instruction Multiple Data)를 이용하여 기존의 문자열 함수보다 더 빨라졌지만, 32비트 머신에서 32비트의 8비트씩 네번 체크하는 것보다 위의 연산을 쓰면 약 8 단위 시간(어셈 명령어의 하나 수행 시간을 1단위 시간이라고 그냥 정합니다.)으로 32비트씩 0을 체크하면 속도가 더 빨라집니다. 단순하게 비교할 것은 아니지만, "4번의 루프가 1번으로 줄어들 수 있다" 정도라고 생각하시면 됩니다. 그렇다면 64비트 머신에서는 64비트 연산으로 "8번의 루프가 1번으로 줄어들 수 있답니다.", SIMD를 이용하면, 지원하는 모드에 따라서 더 줄어들 수 있을 것이랍니다. 위의 코드의 매력적인 부분은 실행 단위 시간이 작은 연산들을 이용하여 연산 수행 시간을 최적화 했다는 것에 있습니다. 어떻게 위 연산을 생각해낼 수 있었을까요? 🤔
가장 쉬워 보이는 것이 사실 가장 어려울 수 있답니다. 쉬워 보이기 때문에, 그 안에 들어간 고민의 깊이를 얕잡아 보는 저의 케이스일지도 모르지만 😒
((x - 0x01010101) & ~x & 0x80808080)
간단한 문자열 함수 속에 또 어떤 고민들이 들어갔는지...... 프로그래밍의 세계는 쉬운 듯 쉽지 않아 보입니다.
https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/string/strlen.c#L80C7-L80C61
다음 내용이 궁금하다면?
이미 회원이신가요?
2023년 12월 27일 오전 11:02
매
... 더 보기코
... 더 보기이
... 더 보기우리는 성장이라는 단어를 좋아합니다.
특히 기업의 입장에서는 성장은 관리해야 할 필수 요소 중 하나죠.
최
... 더 보기