2012-10-20 8 views
1

이미지의 하위 영역에서 많은 작업을 수행합니다. 예를 들어, 100x100 이미지가있는 경우이 이미지를 반복하고 10x10 픽셀 블록을 처리 할 수 ​​있습니다. 예를 들어비 인접 데이터의 명시 적 프리 페치

for(each 10x10 block) 
{ 
    for(each pixel in the block) 
    { 
    do something 
    } 
} 

이 문제는 작은 블록들이 메모리의 인접 청크 (아니라는 것이다 즉 이미지 픽셀은 행 우선 순서로 저장되므로되어 I은 10 × 10 블록의 각 행의 픽셀에 액세스 할 때 블록의 행은 연속적이지만 블록의 행은 인접하지 않습니다.이 블록의 픽셀에 대한 액세스 속도를 높이려면 수행 할 수있는 작업이 있습니까? 아니면 데이터 영역에 빠르게 액세스하는 것이 불가능합니다

많은 독서에서 루프의 유일한 작동으로 픽셀을 처음 읽는 것과 같았습니다.

// First read the pixels 
vector<float> vals(numPixels); 
for(pixels in first row) 
{ 
val[i] = pixels[i]; 
} 

// Then do the operations on the pixels 
for(elements of vals) 
{ 
doSomething(vals[i]) 
} 
내가 무슨 일을하고있어 모두 동시에 그냥 대

:

// Read and operate on the pixels 
for(pixels in first row) 
{ 
doSomething(pixels[i]) 
} 

하지만 난 실제 코드 예제를 찾을 수 없습니다이 작업을 수행하는 방법의 (이론적 설명 대). 이게 진실인가요?

+0

픽셀을 벡터에 복사하면 벡터를 연속 된 메모리 영역에 배치 할 수 있습니다. 인접한 메모리 영역은 캐시 라인에 맞으면 일반적으로 캐시됩니다. – chradcliffe

+0

@chradcliffe하지만 한 번만 사용하면 도움이 될 것입니다. –

+0

@MvG에는이 답변이 있습니다. '__builtin_prefetch'는 사용할 올바른 것입니다. 나는 그 내장에 대해 잊어 버렸다. 사본을 저장하고 값을 한 번만 사용하는 경우 작동합니다. – chradcliffe

답변

1

gcc은 내장 함수가 __builtin_prefetch입니다. 해당 함수와 그 주소를 지원하는 대상에 주소를 전달할 수 있으므로 gcc은 즉시 사용되지는 않더라도 해당 주소가 캐시에로드되도록하는 기계 명령을 내 보냅니다. 당신이 설명 (일명, * 주사선)에 반대 타일

많은 현대 이미지 처리 애플리케이션 스토어 이미지. 예 : 김프 does that. 따라서 이미지가 저장되는 방식을 제어 할 수 있다면 바둑판 식 접근 방식을 사용하면 지역성이 높아져 캐시 미스를 줄이고 성능을 향상시킬 수 있습니다.

+0

스캔 라인 스토리지 시스템을 사용하면 작은 이미지 블록의 모든 주소를 프리 페치해야합니까? 또는 행 블록의 모든 행에있는 첫 번째 픽셀의 주소 만? –

+0

@DavidDoria, 1 바이트의 데이터를 프리 페치 할 때마다 전체 캐시 라인이 캐시로로드됩니다. 이미지와 관련이있는 방식은 CPU 아키텍처, 메모리 정렬 등에 따라 다릅니다. 일반적으로 모든 행 *에 대해 첫 번째 픽셀을 미리로드하면 충분하다고 가정합니다. 확실하지 않은 경우 두 가지 방법을 모두 시도하고 벤치마킹하십시오. – MvG