2012-09-18 5 views
1

관심 영역 (자르기) 알고리즘을 포함하여 일부 이미지 처리 알고리즘이있는 라이브러리가 있습니다. GCC로 컴파일 할 때, 자동 벡터 라이저는 많은 코드를 가속화하지만 Crop 알고리즘의 성능을 악화시킵니다. 특정 루프를 벡터화 기가 무시하도록 플래그를 지정하는 방법이 있습니까? 아니면 더 나은 성능을 위해 코드를 구성하는 더 좋은 방법이 있습니까? SizeX 소스 OriginX의 폭자동 벡터화 관심 영역 (자르기)

for (RowIndex=0;RowIndex<Destination.GetRows();++RowIndex) 
{ 
    rowOffsetS = ((OriginY + RowIndex) * SizeX) + OriginX; 
    rowOffsetD = (RowIndex * Destination.GetColumns()); 
    for (ColumnIndex=0;ColumnIndex<Destination.GetColumns();++ColumnIndex) 
    { 
     BufferSPtr=BufferS + rowOffsetS + ColumnIndex; 
     BufferDPtr=BufferD + rowOffsetD + ColumnIndex; 
     *BufferDPtr=*BufferSPtr; 
    } 
} 

내가 최적화 변경에 대한 아무것도 발견하지 않았습니다 관심

+0

나는 귀하의 질문을 정확하게 undestand 모르겠습니다. 루프를 벡터화하지 않도록 플래그를 지정하거나 더 나은 성능을 위해 구조를 재구성하고 싶습니까? 나에 대한 모순처럼 보입니다. 성능과 관련하여 : 두 범위가 겹칠 수 있습니까? 그렇지 않다면 포인터에'__restrict'를 사용하여 컴파일러에게 알리려합니까? Pointeraliasing은 최적화를위한 큰 진수입니다. 게다가 : 내부 루프에'std :: copy'를 사용하는 것에 대해 생각해 보셨습니까? 그게 더 잘 최적화되고 코드가 더 짧아 질 수 있습니다. – Grizzly

+0

그것은 모순처럼 보입니다,하지만 그 생각입니다. 현재 벡터 라이 제이션은 성능을 저하 시키므로이 루프를 사용하지 않도록 설정하거나 코드를 향상 시키면 내가 생각할 수있는 두 가지 옵션이 있습니다! 나는 제한하고 사본을 줄 것이다. – illumi

+0

이 경우 질문에 작물의 성능이 나 빠졌다는 것을 언급하고 싶을 수도 있습니다. 그것이 의미하는대로 나는 자르기 알고리즘의 성능이 벡터화에 의해 변하지 않은 것으로 가정했다.당신이 아직 그것을 모르는 경우에,'-ftree-vectorizer-verbose = n' 플래그는 옵티마이 저가 무엇을하고 있는지에 대한 더 구체적인 정보를 얻는 데 도움을 줄 것입니다. – Grizzly

답변

0

의 영역의 상단 관심 OriginY의 영역의 왼쪽입니다 루프에 대한 플래그가 있지만이 설명서의 내용에 따라 optimize (herehere) 함수를 사용하여 해당 함수의 최적화 설정을 다음과 같이 다소 재정의 할 수 있습니다.

void foo() __attribute__((optimize("O2", "inline-functions"))) 

여러 기능에 맞게 변경하려면 #pragma GCC optimize을 사용하여 다음 기능 (look here)을 설정할 수 있습니다.

따라서 자동 벡터화를 생략하고 다른 최적화 플래그 세트로 자르기를 포함하는 함수를 컴파일 할 수 있어야합니다. 그건 그 함수에 대한 컴파일 플래그를 하드 코딩하는 단점이 있지만, 내가 찾은 최선이다. 성능 향상을 위해 이미 코멘트에서 언급 한 두 점을 구조 조정에 관하여

마음 (중복되지 수있는 범위를 가정)에 와서 : 컴파일러에게

  • __restrict로 포인터를 선언하는 별칭이 아닙니다 (한 포인터가 가리키는 영역은 함수 내부의 다른 수단으로 액세스 할 수 없습니다). BufferD에 쓰면 BufferS의 내용이 변경되는지 쉽게 알 수없는 경우 포인터의 앨리어싱 가능성이 옵티 마이저의 주요 걸림돌입니다.

  • 복사를 호출하여 내부 루프를 교체 :

    std::copy(BufferS + rowOffsetS, BufferS + rowOffsetS + Destination.GetColumns(), BufferD + rowOffsetD); 
    

    copy 기능은 꽤 잘 (아마도 memmove에 인수를 전달) 최적화 될 가능성이 높습니다, 즉 빠른 코드를 만들 수 있도록하면서 코드 단축 (항상 플러스).

+0

복사를 사용하면이 루프의 자동 벡터화가 비활성화되고 **는 이전보다 약간 나은 성능을 제공합니다. 감사! – illumi