여기에 지나치게 복잡한 답변이 있습니다. Debruin 기술은 입력이 이미 2의 거듭 제곱 일 때만 사용해야합니다. 그렇지 않으면 더 좋은 방법이 있습니다. 2 입력의 거듭 제곱에 대해 Debruin은 _BitScanReverse
내가 테스트 한 어떤 프로세서 보다 훨씬 빠르고 절대적으로 빠릅니다 . 그러나 일반적인 경우 _BitScanReverse
(또는 컴파일러에서 내장 함수가 호출되는 경우)가 가장 빠릅니다 (특정 CPU에서는 마이크로 코딩 될 수 있음).
내장 함수가 옵션이 아닌 경우 일반 입력 처리를위한 최적의 소프트웨어 솔루션이 있습니다.
u8 inline log2 (u32 val) {
u8 k = 0;
if (val > 0x0000FFFFu) { val >>= 16; k = 16; }
if (val > 0x000000FFu) { val >>= 8; k |= 8; }
if (val > 0x0000000Fu) { val >>= 4; k |= 4; }
if (val > 0x00000003u) { val >>= 2; k |= 2; }
k |= (val & 2) >> 1;
return k;
}
이 버전은 대부분의 다른 답변과 달리 끝에 Debruin 조회가 필요하지 않습니다. 제자리에서 위치를 계산합니다.
테이블이 더 바람직 할 수 있지만, 충분히 반복해서 호출하면 테이블 속도 향상으로 인해 캐시 미스 위험이 가려집니다.
u8 kTableLog2[256] = {
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
u8 log2_table(u32 val) {
u8 k = 0;
if (val > 0x0000FFFFuL) { val >>= 16; k = 16; }
if (val > 0x000000FFuL) { val >>= 8; k |= 8; }
k |= kTableLog2[val]; // precompute the Log2 of the low byte
return k;
}
이것은 여기에 제공된 소프트웨어 답변 중 가장 높은 처리량을 생성하지만 가끔 호출하는 경우 첫 번째 스 니펫과 같은 테이블없는 솔루션을 선호합니다.