2012-12-30 2 views
4

OK, 내가 원하는 것은 꽤 정직 :설정 및 설정 해제 64 비트 정수의 특정 비트를

  • 숫자의 N 번째 비트를 설정 (= 그것을 만드는 '1')
  • 설정 해제 N 번째 다수의 비트 (= 그것을 '0')이 (2 개 매크로의 형태로) 지금까지 내 코드입니다

:

#define SETBIT(X,Y)  X|=(1ULL<<(Y)) 
#define UNSETBIT(X,Y) X&=(~(1ULL<<(Y))) 

,

둘 다 잘 작동합니다. 문제는 다음과 같습니다.

  • 최적화 할 수있는 것이 있습니까?
  • 더욱 빨라질 수 있습니까?

(두 가지 작업 모두 초당 몇 백만 번 수행되므로 성능이 중요 이상입니다.)

+1

번호와 번호는이 빨리 당신이 얻을과 같습니다. –

+1

컴퓨터에 대한 asm을 알고 컴파일러가이 기능을 지원한다면 항상 인라인 어셈블리가 있습니다 ... – user1824407

+1

'bitset' 클래스를 사용해 보았습니다 ... – Anirudha

답변

6

매크로를 없애면 컴파일 속도가 약간 빨라질 수 있지만 그게 전부입니다. 비트 트위 더링은 빠르므로 문제가되지 않아야합니다.

이것은 일을하는 관용적 인 방법이며, 나는 물건을 바꾸지 않을 것입니다.

+0

매크로가 없으면 컴파일 속도가 빨라지는데, 특히 어쨌든 존재하는 .h 파일에 있다고 가정 할 때 그렇습니다. 어쨌든 사전 처리 단계는 필수적이며 매크로 대체는 기본적으로 간단한 문자열 교체이므로 컴파일 시간에는 완전히 관련이 없어야합니다. – hyde

+0

@hyde 매크로 대체는 전처리 과정에서 발생하며 전체 편집 프로세스의 일부입니다. 그것은 어떻게 부적절 할 수 있습니까? –

+0

제 말은,이 매크로들을 가지고 컴파일 시간이 밀리 세컨드 (millisecond) 또는 그 이상으로 증가한다면 ... 관련이 있다고 부를 것입니까? – hyde

2

매크로는 최적 일 때 입니다. 따라서 최적화가 수행되는 경우 컴파일러는 해당 표현식을 인식 할 수 있습니다.

더 빠른 대안은 더 나은 대안이있는 경우 사용을 피하는 것입니다. 동일한 멀티 비트 연산 (예 : 비트 0, 2 및 4 켜기)을 자주 수행하는 경우 이러한 연산을 모두 수행하여 무언가를 얻을 수 있습니다. 복수 SETBIT을 사용하는 대신 단일 또는을 입력하십시오.

3

이 설정하고 잠재적으로 속도까지이 매크로에 이러한 작업의 리눅스 어셈블리 구현을 살펴 가질 수 원하는 경우

C.

에 비트를 클리어의 표준 방법입니다. x86에 대한 예를 들어

: __clear_bit__set_bit 인라인 함수에 대한

http://lxr.linux.no/linux/arch/x86/include/asm/bitops.h

봐. 모든

+0

실제로 원 자성 및 재정렬 불능 보장이 필요 없다면 그는 대신 __set_bit 및 __clear_bit을 살펴 봐야합니다. –

+0

@MatteoItalia 감사합니다. – ouah

+0

실제로 OP는 Windows, Linux 또는 프로세서에 관계없이 컴파일러가 생성 한 어셈블리 코드를 확인해야합니다. –

2

첫째, 당신은 이렇게 될 매크로를 수정해야합니다 :

#define SETBIT(X,Y)  ((X) |= 1ULL << (Y)) 
#define UNSETBIT(X,Y) ((X) &= ~(1ULL << (Y)))) 

SETBIT(a, 2) + 1; 같은 그런 식으로 코드가 더 기대처럼 작동 것이라고 예상대로 SETBIT(1+a, 2);이 오류가 발생합니다.

그런 식으로 매크로를 사용하지는 않겠지 만 여분의 괄호는 아무렇게나 사용할 수 있으며 매크로 관련 문제를 해결하는 데 PITA를 사용할 수 있습니다. 매크로는 항상 () 또는 {}입니다.

ADDITION : 다음

X = X OR (0xFFFFFFFFFFFFFFFE ROL Y) 

: 컴파일 시간에 알려져 있지 Y 가정 인라인 어셈블리 및 비트 회전 동작으로 CPU 및 으로 UNSETBIT는 NOT ... 의사 코드 피 빠르게 할 수있다 그 매크로가수록 효율적있는 동안 (C 컴파일러는 이상적인 조립 지침에 최적화해야한다), 당신은 아마도 같은 여러 비트를 조작하는 매크로를 제공해야한다 : 또한

#define SET2BITS(X, B1, B2)  ((X) |= 1ULL << (B1) | 1ULL << (B2)) 

기능처럼 (컴파일러 최적화 아마 어쨌든 같은 최종 결과를 달성 할 수 있지만) 어떤 상황에서보다 효율적으로 될 수 내부 표현을 사용하는 매크로 :

#define BITSETVAL(X, B)  ((X) | 1ULL << (B))