Я пытаюсь применить фильтр 1x3, 3x1 в 3D-структуре (том).
Например, если имеется 20 (смещ_по_столбцы) х 10 (строк) х 10 (глубина) структуры,Фильтрация в 3D пространстве с помощью CUDA, горизонтальный доступ быстрее, чем вертикальный доступ?
for(int depth = 0; depth < 10; depth++)
Apply image filter(depth);
применить фильтр к 2d изображений (20x10) 10 раз. каждый фрагмент изображения отличается.
во-первых, я выделить 3D структуру, как
// COLS = 450, ROWS = 375, MAX_DISPARITY = 60
cudaPitchedPtr volume;
cudaExtent volumeExtent = make_cudaExtent(COLS, ROWS, MAX_DISPARITY);
HANDLE_ERROR(cudaMalloc3D(&volume, volumeExtent));
и памяти равным нулю для стабильного производства. пока все хорошо, пока копировать изображение в том объеме.
При применении фильтра 3x1, как показано ниже, его расчет составлял 6 мсек.
Apply_3by1 << <ROWS, COLS, COLS>> > (volume, COLS, ROWS);
__global__ void Apply_3by1 (cudaPitchedPtr src, unsigned int COLS, unsigned int ROWS)
{
const unsigned int x = threadIdx.x;
const unsigned int y = blockIdx.x;
extern __shared__ unsigned char SharedMemory[];
for (int dispCnt = 0; dispCnt < MAX_DISPARITY; dispCnt++)
{
if (x < dispCnt) continue;//exception for my algorithm.
unsigned char dst_val = *GET_UCHAR_PTR_3D(src, x, y, dispCnt);
SharedMemory[x] = dst_val;
__syncthreads();
unsigned char left;
int leftIdx = x - 3;
if (leftIdx < 0)//index underflow
left = 0;
else
left = SharedMemory[leftIdx];
unsigned char right;//index overflow
int rightIdx = x + 3;
if (COLS < rightIdx)
right = 0;
else
right = SharedMemory[rightIdx];
*GET_UCHAR_PTR_3D(src, x, y, dispCnt) += left + right;
}
}
, но когда я применяю вертикальное направление фильтра 1x3, время его вычисления составляло 46 мсек.
Apply_1by3 << <COLS, ROWS, ROWS >> > (volume, COLS, ROWS);
__global__ void Apply_1by3 (cudaPitchedPtr src, unsigned int COLS, unsigned int ROWS)
{
const unsigned int x = threadIdx.x;
const unsigned int y = blockIdx.x;
extern __shared__ unsigned char SharedMemory[];
for (int dispCnt = 0; dispCnt < MAX_DISPARITY; dispCnt++)
{
unsigned char my_val = *GET_UCHAR_PTR_3D(src, y, x, dispCnt);
SharedMemory[x] = my_val;
__syncthreads();
if (y < dispCnt) continue;
int topIdx = x - 3;
unsigned char top_value;
if (topIdx < 0)
top_value = 0;
else
top_value = SharedMemory[topIdx];
int bottomIdx = x + 3;
unsigned char bottom_value;
if (ROWS <= bottomIdx)
bottom_value = 0;
else
bottom_value = SharedMemory[bottomIdx];
*GET_UCHAR_PTR_3D(src, y, x, dispCnt) += bottom_value + top_value;
}
}
Я понятия не имею, почему доступ к вертикальному направлению медленнее горизонтального доступа, почти 8 раз. если вы знаете, почему это время доступа отличается, пожалуйста, просветите меня.
Мои извинения, я забыл добавить
#define GET_UCHAR_PTR_3D(pptr, x, y, d) \
(unsigned char*)((char*)(pptr).ptr + (sizeof(unsigned char)* x) + ((pptr).pitch * y) + ((pptr).pitch * (pptr).ysize * d))
Горизонтальный доступ может быть хорошо скомбинирован, а вертикальный доступ - нет. Это просто предположение, не зная, что делает GET_UCHAR_PTR_3D'. Вам необходимо предоставить * полный код *, т. Е. [MCVE] (http://stackoverflow.com/help/mcve), который демонстрирует разницу. Это то, что кто-то может копировать, вставлять, компилировать и запускать, и видеть проблему, не добавляя ничего или ничего не менять. Голосование закрывается. –
Спасибо, Это плохо. Я редактирую, что такое GET_UCHAR_PTR_3D. Я опишу детали своего кода, как скоро смогу –