Community

Determine if a word has a zero byte

표준 라이브러리의 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

알림

알림이 없습니다