在兩個不同的體系結構(GTX480和GTX TITAN)中,使用nppiCopyConstBorder_8u_C1R
函數的性能下降,也涉及到不同的CUDA版本(分別爲v5.0和v5.5)。性能下降nppiCopyConstBorder_8u_C1R
在第一種情況(GTX480和CUDA 5.0)的功能的執行時間是
T = 0.00005 seconds
在第二種情況下(GTX TITAN和CUDA 5.5)的執行時間是
我用以下代碼複製了此行爲:
// GTX480 nvcc -lnpp -m64 -O3 --ptxas-options=-v -gencode arch=compute_20,code=sm_20 --compiler-options -use_fast_math
// GTXTITAN nvcc -lnppi -m64 -O3 --ptxas-options=-v -gencode arch=compute_35,code=sm_35 --compiler-options -use_fast_math
#include <stdlib.h>
#include <stdio.h>
// CUDA
#include <cuda.h>
#include <cuda_runtime_api.h>
// CUDA Nvidia Performance Primitives
#include <npp.h>
#include <assert.h>
#define w 256 // width
#define h 256 // height
#define b 16 // extra border
#define BORDER_TYPE 0
int main(int argc, char *argv[])
{
// input data
Npp8u* h_idata[w*h];
// output data
Npp8u* h_odata[(w+b)*(h+b)];
/* MEMORY ALLOCTION AND INITIAL COPY OF DATA FROM CPU TO GPU */
Npp8u *i_devPtr, *i_devPtr_Border;
// size of input the data
int d_Size = w * h * sizeof(Npp8u);
// allocate input data
CUDA_CHECK_RETURN(cudaMalloc((void**) &i_devPtr, d_Size));
// copy initial data to GPU
CUDA_CHECK_RETURN(cudaMemcpy(i_devPtr, h_idata, d_Size, cudaMemcpyHostToDevice));
// size of output the data
int d_Size_o = (w+b) * (h+b) * sizeof(Npp8u);
// allocation for input data with extended border
CUDA_CHECK_RETURN(cudaMalloc((void**) &i_devPtr_Border, d_Size_o));
// create struct with ROI size given the current mask
NppiSize SizeROI = {w, h};
NppiSize SizeROI_Border = { SizeROI.width + b, SizeROI.height + b };
// create events
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
// NPP Library Copy Constant Border
cudaEventRecord(start, 0);
NppStatus eStatusNPP = nppiCopyConstBorder_8u_C1R(i_devPtr,SizeROI.width, SizeROI,
i_devPtr_Border, SizeROI_Border.width, SizeROI_Border,
b, b, BORDER_TYPE);
cudaDeviceSynchronize();
assert(NPP_NO_ERROR == eStatusNPP);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
float milliseconds = 0;
cudaEventElapsedTime(&milliseconds, start, stop);
printf("T= %1.5f sg\n", milliseconds/1000.0f);
// copy output data from GPU
CUDA_CHECK_RETURN(cudaMemcpy(h_odata, i_devPtr_Border, d_Size_o, cudaMemcpyDeviceToHost));
/* free resources */
cudaFree(i_devPtr);
cudaFree(i_devPtr_Border);
CUDA_CHECK_RETURN(cudaDeviceReset());
return 0;
}
問:任何人都知道這個問題?
這使我問以下問題:
問:如何nppiCopyConstBorder_8u_C1R
實施?該功能是否涉及將數據從設備複製到主機,擴展主機中的邊界並將結果複製到設備?
PS:帶有TITAN的機器將GPU安裝在分離的主板上,專門設計用於多個PCIe連接,並通過PCIe線連接。在我已經測試的其他內核的配置中,我沒有看到任何缺陷。
你可以嘗試使用nvprof運行API跟蹤嗎?我猜你的時間可能是過去一段時間內發生的事情的受害者,現在在內核啓動時現在正在懶惰地發生。內核功能仍然需要幾微秒,但運行它的cuLuanch需要幾百毫秒。 – talonmies
@talonmies我將在兩臺機器上檢查API跟蹤。 – pQB