사실 이건 자주 사용할 수 있는건 아닌데, ( 약간은 사용된 연산과 전체 코드 흐름 종속적인 부분이 강함 )
inline int test1( const int p )
{
if( ( p & 0x000000FF ) ) return 0;
if( ( p & 0x0000FF00 ) ) return 1;
if( ( p & 0x00FF0000 ) ) return 2;
if( ( p & 0xFF000000 ) ) return 3;
return -1;
}
아이러니 하게도 이런 코드를 자주 만날 수 있지.
어느 바이트에 0이 있는지, 값이 있는지를 찾는 경우.
즉, 마치 BSR 과 BSF instruction 비슷한게 필요한 경우 말야.
케이스가 작으면 배열에 때려 넣으면 되는데,
이처럼 표현 대역이 크다든지,
여러 바이트에 값이 나뉘어져 있는 중에
가장 MSB 에 가까운쪽, 혹은 LSB 에 가까운 쪽을 알고싶다든지 하는 경우
어셈블리를 쓰지 않으려면 좀 귀찮아지지.
( RISC 나 EISC 같은 류, ARM 같은 코어에서 작업한다든지 ? )
그런 경우 콤마 연산자와 short circuit 을 이용할 수 있어.
다음과 같은 예지. ( 요건 내가 고안한거 맞음 키키.누군가는 쓸 지라도 )
inline int test2( const int p )
{
int r = -1;
if( ( r = 0, ( p & 0x000000FF ) ) ||
( r = 1, ( p & 0x0000FF00 ) ) ||
( r = 2, ( p & 0x00FF0000 ) ) ||
( r = 3, ( p & 0xFF000000 ) ) ) return r;
return -1;
}
RDTSC 로 100번 수행해 성능을 알아봤을 때,
volatile int p = 0x000000FF; // TEST1 : 429 +- 20 / TEST2 : 429
volatile int p = 0x0000FF00; // TEST1 : 459 +- 10 / TEST2 : 435
volatile int p = 0x00FF0000; // TEST1 : 605 +- 10 / TEST2 : 459
volatile int p = 0xFF000000; // TEST1 : 623 +- 10 / TEST2 : 477
volatile int p = 0x00000000; // TEST1 : 626 +- 20 / TEST2 : 459
의 성능을 보이게 돼.
여기서는 부호비트 종속적인 연산을 쓰지 않았기 때문에 unsigned 냐 signed 냐는 중요하지 않아.
이 실험에서 알 수 있는건 여러가지야. ( 누누히 말하지만 나는 관찰력 짱이라 실험 잘함 으헤헤 )
1. test1 은 clock 이 코드의 실행 순서에 따라 단조 증가함에 반해,
test2 는 코드의 실행 순서를 좀 따르는듯 보이지만 완전히 그렇지 않다는거.
( 0 을 입력조건으로 주었을 때 오히려 감소함 )
2. test2 는 매 번 조금씩 불어나는데 반해( 100번 연산인 것 치고 1회 연산으로 보면 1클럭 보다 작은 증가지 )
test1 은 459 에서 605 로 훅 뛴다는거.
3. 그렇다면 실험 결과가 이상한건가 ?
그렇지 않아.
하위 16비트만을 비트 연산할때와 상위 16비트를 계산할때 크게 벌어진다는 것,
즉 super pipeline 단계중, execute 단계에서의 세분화가
word->byte( ->bit ? 는 아니겠지 코어 제조 비용이 급증할테니 ㅋㅋ ) 단위로 분기되어 쪼개져 있다는거지.
고로 상위 16bit word의( &0xFFFF0000 ) 연산이 시행되는 시점에서 아얘 0 이면 바로 빠져 나왔고,
그 결과 분기까지의 절차적 거리가 동일하기 때문에( 어차피 return 말곤 할게 없음 ),
두 가지 케이스( 0x00FF0000 과 0x00000000 의 입력조건 )의 클럭수가 같게 나오는거지.
따라서 비트 연산도 상위 워드는 상위 워드끼리, 하위 워드는 하위 워드끼리 모아줘야
컴파일러의 short circuit 상의 최적화 뿐만 아니라
제대로 super pipeline 상의 short circuit 의 효과를 볼 수 있다는 것.
return code 를 하나로 묶냐 아니냐 에 따라 short circuit 효율 자체가 크게 좌우될 수 있다는 것.
콤마 연산으로 상태를 마킹하고( overwrite 만 하기 때문에 writeback + readout 비용은 없음 )
비용이 비싼 연산 앞에 묻어가는 트릭을 말씀드렸슴돠~
물러갑니다~
첫댓글 안주무세뇨?
ㅋㅋ 지난 글들 스크랩 중.
ㅠㅠ뮤슨말인지 모르겠다 ㅠㅠ