programing

특별한 경우:%보다 빠릅니까?

stoneblock 2023. 9. 6. 21:44

특별한 경우:%보다 빠릅니까?

는 이 게시물에 대한 선택된 답변을 보았습니다.

그래서 깜짝 놀랐어요.(x & 255) == (x % 256)만약 x가 부호가 없는 정수라면, 나는 항상 대체하는 것이 말이 되는지 궁금했습니다.%와 함께&인에x % n위해서n = 2^a (a = [1, ...])그리고 x는 양의 정수입니다.

이것은 프로그램이 어떤 가치를 다룰지 알고 컴파일러가 다루지 않기 때문에 인간으로서 나는 결정할 수 있는 특별한 경우이기 때문입니다.프로그램이 모듈로 작업을 많이 사용하는 경우 성능이 크게 향상될 수 있습니까?

물론이죠, 그냥 디스어셈블리를 정리해서 볼 수 있을 겁니다.하지만 이것은 단지 하나의 컴파일러/아키텍처에 대한 제 질문에 대답해줄 뿐입니다.이것이 원칙적으로 더 빠른지 알고 싶습니다.

만약 당신의 적분형이 부호가 없는 경우, 컴파일러가 그것을 최적화할 것이고, 결과는 같습니다.서명이 되면 뭔가 달라요

이 프로그램:

int mod_signed(int i) {
  return i % 256;
}
int and_signed(int i) {
  return i & 255;
}
unsigned mod_unsigned(unsigned int i) {
  return i % 256;
}
unsigned and_unsigned(unsigned int i) {
  return i & 255;
}

(-O3와 함께 GCC 6.2에 의해, Clang 3.9는 매우 유사한 코드를 생성함) 다음과 같이 컴파일됩니다.

mod_signed(int):
        mov     edx, edi
        sar     edx, 31
        shr     edx, 24
        lea     eax, [rdi+rdx]
        movzx   eax, al
        sub     eax, edx
        ret
and_signed(int):
        movzx   eax, dil
        ret
mod_unsigned(unsigned int):
        movzx   eax, dil
        ret
and_unsigned(unsigned int):
        movzx   eax, dil
        ret

의 결과 어셈블리.mod_signed다른 이유는

곱셈, 나눗셈 또는 모듈러스 식에 대한 두 피연산자의 부호가 같으면 결과는 양수입니다.그렇지 않으면 결과가 음수입니다.모듈러스 연산 부호의 결과는 구현에 정의되어 있습니다.

그리고 AFAICT의 대부분의 구현은 모듈러스 표현의 결과가 첫 번째 피연산자의 부호와 항상 동일하다고 결정했습니다.설명서를 참조하십시오.

이런 이유로,mod_signed에 최적화되어 있습니다(nwellnhof의 코멘트로부터).

int d = i < 0 ? 255 : 0;
return ((i + d) & 255) - d;

논리적으로, 우리는 그것을 증명할 수 있습니다.i % 256 == i & 255부호가 없는 모든 정수에 대해서, 우리는 컴파일러가 그 일을 할 것이라고 믿을 수 있습니다.

나는 gcc로 몇가지 측정을 했고, 만약 a의 주장이/아니면%는 2의 거듭제곱인 컴파일된 시간 상수이며, gcc는 이를 해당 비트 연산으로 변환할 수 있습니다.

다음은 분할에 대한 몇 가지 벤치마크입니다. 곱셈과 분할 중 더 나은 성능을 갖는 은 무엇입니까?보다시피, 2의 거듭제곱이 정적으로 알려진 나눗셈의 실행 시간은 다른 정적으로 알려진 나눗셈의 실행 시간보다 현저하게 짧습니다.

그래서 만약에/그리고.%정적으로 알려진 power-of-two 인수는 당신의 알고리즘을 비트 ops보다 더 잘 설명합니다. 자유롭게 선호하세요./그리고.%. 당신은 훌륭한 컴파일러로 어떤 성능도 잃지 말아야 합니다.

언급URL : https://stackoverflow.com/questions/40759800/in-special-cases-is-faster-than