내가 가지고 올 수있는 최선이이 입력 값의 제약을 활용
40072e: 29 c8 sub %ecx,%eax
400730: 29 ca sub %ecx,%edx
400732: 09 d0 or %edx,%eax
400734: a8 80 test $0x80,%al
400736: 74 17 je 40074f <main+0x3f>
하나의 조건 분기를 생성 gcc -O2
이
char a, b, c;
std::cin >> a >> b >> c;
if (((b-a) | (c-a)) & 0x80) {
// a > b || a > c
}
입니다 26보다 작 으면 b
에서 a
을 뺀 값은 a > b
일 때 음수 값을, 두 번째 값은 7
이되도록 설정합니다. 같은 경우 0으로 적용됩니다.. 그 다음에 또는 비트 모두 7
은 a > b || a > c
인지 여부를 나타냅니다. 마지막으로 비트 7
은 이고,은 0x80이고 분기점은 검사합니다.
업데이트 : 호기심에서 벗어난이 4 가지 코딩 방법으로 시간을 조정했습니다. 테스트 데이터를 생성하기 위해 간단한 선형 합동 의사 난수 생성기를 사용했습니다. 나는 1 억회 반복을 위해 루프를 수행했다.단순함을 가정 할 때 조건이 true이면 카운터에 5를 더하고, 그렇지 않으면 아무것도하지 않겠다고 가정했습니다. 나는 -O2
최적화 수준을 사용하여 Intel Xeon X5570 @ 2.93GHz
에 g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
을 사용하여 시간을 측정했습니다. 우리는 하나입니다 마스크를 생성하는 부호 확장을 사용하여 내 대답에 제안에 수정 가장 빠른
#include <iostream>
unsigned myrand() {
static unsigned x = 1;
return (x = x * 1664525 + 1013904223);
}
int main() {
size_t count = 0;
for(size_t i=0; i<100000000; ++i) {
int a = 1 + myrand() % 26;
int b = 1 + myrand() % 26;
int c = 1 + myrand() % 26;
count += 5 & (((b-a) | (c-a)) >> 31); // 0.635 sec
//if (((b-a) | (c-a)) & 0x80) count += 5; // 0.660 sec
//if (a > std::max(b,c)) count += 5; // 0.677 sec
//if (a > b || a > c) count += 5; // 1.164 sec
}
std::cout << count << std::endl;
return 0;
}
됩니다 : 여기
코드 (조건부 변형 중 하나를 제외한 모든 주석)의 32
1s
또는 32
0s
이 있으며 조건이 거짓인지 여부에 따라 다르며이를 사용하여
5
을 마스크하여 5 또는 0을 추가합니다.이 변형에는 분기가 없습니다. 시간은 각 행에 주석으로 표시됩니다. 가장 느린 것은 원래 식
(a > b || a > c)
입니다.
정확히 무엇을 최적화하려고합니까? – delnan
나는 적어도 (A * 2)> (b + c)가 실제로 더 최적이라고 생각하지 않는다. 적어도 실행 속도를 향상시키고 싶다고 올바르게 이해한다면 말이다. – Aleph
만약'if'에서'a> b'가 나오면'a> c'의 평가가 생략된다는 것을 알고 계셨습니까? – Zeta