opnecl에서 2D 컨볼 루션으로 벤치 마크 된 Xeon Phi의 성능은 컴파일러 사용 벡터화에서도 openmp 구현보다 훨씬 우수합니다. Openmp 버전은 파이 네이티브 모드로 실행되었으며, 타이밍은 계산 부분 : For-loop 만 측정되었습니다. opencl 구현에서 타이밍은 커널 계산을 위해서만 사용되었으며 데이터 전송은 포함되지 않았습니다. OpenMp-enbaled 버전은 2,4,60,120,240 개의 스레드로 테스트되었습니다. - 240 개의 스레드가 균형 잡힌 스레드 선호도 설정을위한 최상의 성능을 제공했습니다. 그러나 Opencl은 240 스레드의 오픈 엠프베이스 라인에서도 pragma-enbled vectorization이 소스 코드로 17 배 정도 향상되었습니다. 입력 이미지 크기는 1024x1024에서 최대 16384x16384이고 필터 크기는 3x3에서 최대 17x17입니다. 호출이 실행될 때 opencl은 openmp보다 낫습니다. 이것은 opencl의 예상되는 속도인가 ?? 진실한 너무 좋은 것 같다.OpenCL on Xeon Phi : 2D 컨볼 루션 경험 - OpenCL 대 OpenMP
EDIT :
편집 (OpenMP의)
icc Convolve.cpp -fopenmp -mmic -O3 -vec-report1 -o conv.mic
Convolve.cpp(71): (col. 17) remark: LOOP WAS VECTORIZED
소스 (Convole.cpp)
void Convolution_Threaded(float * pInput, float * pFilter, float * pOutput,
const int nInWidth, const int nWidth, const int nHeight,
const int nFilterWidth, const int nNumThreads)
{
#pragma omp parallel for num_threads(nNumThreads)
for (int yOut = 0; yOut < nHeight; yOut++)
{
const int yInTopLeft = yOut;
for (int xOut = 0; xOut < nWidth; xOut++)
{
const int xInTopLeft = xOut;
float sum = 0;
for (int r = 0; r < nFilterWidth; r++)
{
const int idxFtmp = r * nFilterWidth;
const int yIn = yInTopLeft + r;
const int idxIntmp = yIn * nInWidth + xInTopLeft;
#pragma ivdep //discards any data dependencies assumed by compiler
#pragma vector aligned //all data accessed in the loop is properly aligned
for (int c = 0; c < nFilterWidth; c++)
{
const int idxF = idxFtmp + c;
const int idxIn = idxIntmp + c;
sum += pFilter[idxF]*pInput[idxIn];
}
}
const int idxOut = yOut * nWidth + xOut;
pOutput[idxOut] = sum;
}
}
}
소스 2 (convolve.cl)
__kernel void Convolve(const __global float * pInput,
__constant float * pFilter,
__global float * pOutput,
const int nInWidth,
const int nFilterWidth)
{
const int nWidth = get_global_size(0);
const int xOut = get_global_id(0);
const int yOut = get_global_id(1);
const int xInTopLeft = xOut;
const int yInTopLeft = yOut;
float sum = 0;
for (int r = 0; r < nFilterWidth; r++)
{
const int idxFtmp = r * nFilterWidth;
const int yIn = yInTopLeft + r;
const int idxIntmp = yIn * nInWidth + xInTopLeft;
for (int c = 0; c < nFilterWidth; c++)
{
const int idxF = idxFtmp + c;
const int idxIn = idxIntmp + c;
sum += pFilter[idxF]*pInput[idxIn];
}
}
const int idxOut = yOut * nWidth + xOut;
pOutput[idxOut] = sum;
}
결과 OpenMP의 비교 (OpenCL과 비교)) :
image filter exec Time (ms)
OpenMP 2048x2048 3x3 23.4
OpenCL 2048x2048 3x3 1.04*
* 원시 커널 실행 시간. PCI 버스를 통한 데이터 전송 시간은 포함되어 있지 않습니다.
다른 방식으로 최적화되었을 가능성이 큰 두 가지 코드 세트를 사용하고 있습니다. OpenMP를 직접 작성 했습니까? 코드를 게시하십시오. 최적화되지 않았을 가능성이 있습니다. OpenCL에서 벡터 유형 (예 : float4)을 사용합니까? 이것들은 SSE/AVX를 사용할 것입니다. SSE/AVX를 사용하려면 OpenMP만이 스레드를 처리합니다. 직접 수행해야합니다. –
또한 Xeon Phi는 OpenCL에서 이용할 수있는 512 비트 폭의 자체 SIMD (AVX512)를 가지고 있습니다. OpenMP가이 작업을 수행하지 않습니다. –
Intel은 특정 커널의 수평 벡터화를 수행 할 가능성이 매우 높습니다. 즉 단일 Xeon Phi 코어가 단일 코어에서 동시에 16 개의 스레드를 실행할 수 있습니다 (하나의 스레드가 32 비트 val에서 작동한다고 가정 할 때). 이것은 자연스럽게 커널에 의존하며 이러한 모든 종류의 처리를 쉽게 수정할 수있는 것은 아닙니다. – sharpneli