2016-07-24 4 views
1

각각의 값 및 실행 코드 모음을 검색하면서 특정 품질을 찾은 다음 부울 값을 설정하고 코드를 실행할 때 다시 되돌리고 싶습니다. 그 객체는 조건부를 실행하여 부울을 해제해야하는지 여부를 확인하는 것이 더 빠릅니까? 아니면 모든 루프에서 간단하게 해제하는 것이 더 빠릅니까?조건부 검사와 변수 설정을 여러 번 반복합니다. 낮은 수준의 최적화

예를 들면 (사이비 코드) :

bool found = false; 
for(particle in literallyAHaystack) { 
    bool isNeedle = particle == "needle"; 

    if(isNeedle) { 
     found = true; 
    } 

    // [some code that uses the 'found' variable] 

    if(isNeedle) { 
     found = false; 
    } 
} 

bool found = false; 
for(particle in literallyAHaystack) { 
    bool isNeedle = particle == "needle"; 

    if(isNeedle) { 
     found = true; 
    } 

    // [some code that uses the 'found' variable] 

    found = false; // a conditional no longer surrounds this statement 
} 

나는 이것이 매우 낮은 수준의 보통-무의미 최적화 이해하지만, 난 여전히 진실에 관심

대 그것의. 나는 그 질문의 사소한 일로 누구에게도 기분을 상하게하지 않기를 바란다.

+0

어 ... 왜 isNeedle과 found?를 모두 가지고 있습니까? 그들은 불필요한 것처럼 보입니다. – user2357112

+0

@ user2357112 : 아이디어는'found'가'if' 내부에 무언가에 의해 설정 될 수 있다고 상상하는 것입니다, 그래서 이전 검사의 결과를 기록하기 위해 boolean없이 중첩 된'if()'절로 전체를 작성하면 코드 중복. –

답변

1

bool found이 로컬 변수 인 경우 무조건적으로 false으로 설정하면 대부분의 경우 거의 모든 CPU 아키텍처에서 모든 경우에 훨씬 나을 것입니다. 그것이 분기 논리의 일부가되는 것보다 컴파일러 출력에 존재한다면 아마도 레지스터에만있을 것입니다. 쓰기 작업은 가능한 가장 저렴한 작업 중 하나인데, 분기 작업보다 훨씬 저렴합니다.

메모리가 닳 았을지라도 후기 입 캐시가 일반적이므로 큰 공유 캐시 또는 주 메모리로 트래픽을 생성하지 않고 L1에있는 동일한 위치에 반복적으로 저장하면 반복적으로 저장됩니다.


컴파일러가 실제로 (인텔 스웰에서 예) ~ 5주기의 저장 - 전송 지연을 초래할 것이다 플래그 다음 반복에 의하면, 각 루프의 끝에서 메모리에 플래그를 저장하는 코드를 방출하면

.

하지만 문제가 발생하면 코드를 최적화하지 않는 것이 컴파일러의 잘못입니다. 이것이 바로 asm으로 작성하는 대신 컴파일러를 사용하는 이유입니다. 컴파일러는 found 변수를 완전히 최적화 할 수 있습니다. 즉, 잘, 그리고 x86에서 이런 종류의 물건에 대한 자세한 내용은 당신의 C.

구조 조정의 인수되지는 태그 위키 http://agner.org/optimize/ 및 기타 링크를 참조하십시오.

은 어쩌면 수, http://gcc.godbolt.org/에 그것을 넣어 코드를 컴파일하는 방법을 참조 (및 O3 -march=haswell -ffast-math 또는 무언가를 사용합니다.)


found 글로벌 경우 (그리고 마지막으로 다른 스레드에 의해 수정되었을 수 있습니다)하려면 처음에는 코드를 읽는 것이 중요하므로 코드를 실행하는 코어는 다른 코어의 캐시 라인 복사본을 무효화 할 필요가 없습니다.

다른 스레드에서 사용할 수있는 공유 상태 구조체 (잠금으로 보호 된 중요한 섹션의 코드에서 사용됨)의 일부인 플래그를 상상하고 있습니다.(이 경우 끔찍한 디자인 일 것입니다. 왜냐하면 사용 후 항상 foundfalse이므로 지속성이 없으므로 로컬이어야합니다.)

여전히 조건 분기를 사용하는 것이 가치가 없을 것입니다. 그 가게를 피하십시오. 루프 반복 (즉, 바늘이 일치하는 경우)에서 플래그가 전혀 수정되지 않으면 원하는만큼 자주 수정할 수 있습니다.

상점을 피하는 것이 점포에서 같은 위치로 이동할 수있는 경우에만 유용합니다. 캐시 작업.

벡터화 할 때, 4 개의 벡터가 아닌 3 개의 벡터 요소를 쓰고 싶다면 저장소에 중첩 된 저장소를 쓰는 것이 유용 할 수 있습니다. 저장하는 대상의 끝을 넘어서 쓰는 것이 좋습니다. 예 : this code에 있습니다.

+0

정말 고마워요. 예제 코드가 완전한 의미는 아니지만 질문에 정확히 대답했다는 것을 알고 있습니다. –

0

조건 검사가 없으므로 점핑이 필요하지 않으므로 두 번째는 "빠릅니다".

눈에 띄는 속도가 빨라 집니까? 거의 확실하지. 그럼에도 불구하고, 컴파일러 이 최적화를 이미 만들었지 만 나에게 그다지 인용하지는 않는다.