저는 현재 추력 라이브러리를 사용하여 GPU에서 벡터의 합계와 최대 감소를 수행하는 CUDA 어플리케이션을 보유하고 있습니다. 특정 벡터 길이의 경우 벡터를 호스트로 보내고 C++의 합계 및 최대 감소를 계산하면 훨씬 더 빠릅니다.gcc-via-nvcc가이 합계와 최대 감소를 벡터화합니까?
합계와 최대 감소는 호스트에서 벡터화 할 수 있어야합니다. 호스트의 메모리는 선형/연속적이며 컴파일러는 이것을 지원합니다 (GCC). 주어진 타이밍을 감안할 때, 컴파일러가 코드를 벡터화하는 것 같지만 어떻게 확인할 수 있습니까? 컴파일러 최적화에 대한 경험이 없지만 사용할 수있는 일부 pragma 문이 있다는 것을 알고 있습니다. 인터넷 검색으로 정보를 거의 찾을 수 없습니다. 또한 이해할 수 없으므로 확인을 위해 어셈블리를 파헤 치지 않을 것입니다. 컴파일러 설정 (GCC 또는 NVCC에서)을 사용하여 호스트에서 벡터화를 강제 실행하거나 코드가 벡터화되었다는 확인을 찾을 수 있습니까?
합계와 최대 감소에 대해 작성한 함수는 다음과 같습니다. nvcc 컴파일러는 함수가 CUDA 코드를 포함하기 때문에 궁극적으로이를 컴파일합니다.
void calc_vector_max_host(double& maxval, double *const vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? max
maxval = *vec_h;
double* temp = vec_h;
for(int i = 1; i < len; i++, temp++)
{
if(*temp > maxval)
{
maxval = *temp;
}
}
}
void calc_vector_sum_host(double& sum, double *const vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? sum
sum = 0.0;
double* temp = vec_h;
for(int i = 0; i < len; i++, temp++)
{
sum += *temp;
}
}
편집 : 다음은 gcc가 자동 벡터화하는 데 필요한 수정 사항입니다. 주석에 나열된 컴파일러 옵션도 필요했습니다.
void calc_vector_max_host(double& maxval, double *const __restrict__ vec_h, const double *const __restrict__ vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? max
double local_maxval = vec_h[0];
for(int i = 1; i < len; i++)
{
double val = vec_h[i];
if(val > local_maxval)
{
local_maxval = val;
}
}
maxval = local_maxval;
}
void calc_vector_sum_host(double& sum, double *const __restrict__ vec_h, const double *const vec_d, int len)
{
//copy device vector to host
gpuErrchk(cudaMemcpy(vec_h, vec_d, len*sizeof(double), cudaMemcpyDeviceToHost));
//vectorized? sum
double local_sum = 0.0;
for(int i = 0; i < len; i++)
{
local_sum += vec_h[i];
}
sum = local_sum;
}
몇 가지 의견은 기록 용으로 만 제공됩니다. gcc 옵션 웹 페이지에 대한 링크가 도움이되었습니다. 결국 게시 된 코드는 자동 벡터 라이징이 아니 었습니다. 이것은 일부 누락 된 컴파일러 옵션 때문이었습니다. 특히, -xcompiler 플래그를 사용하여 -ftree-vectorize -msse2와 -fast-math를 모두 전달해야만 벡터화 할 코드를 얻을 수 있었고 ftree-vectorize-verbose = 6을 사용하여 자동 벡터화 컴파일러 출력을 얻을 수있었습니다. 나는 리눅스를 사용 중이며 objdump를 시도했지만이 문제에 대해 어셈블리 덤프를 찾지 못했습니다. 또한 편집 된 기능에 몇 가지 문제가있었습니다. –