【发布时间】:2017-01-31 20:12:23
【问题描述】:
我最近使用 cuda 编写了一些简单的代码,但虽然我听说它可以加快速度,但我没有看到太多。 例如,我用 cuda 编写了 2 个代码(不使用任何库,如 NPP 和 ...)。
首先是一个模糊滤镜(没有纹理记忆)。
第二个基于模糊的分割(包括一些每个元素的乘法、加法、除法和一些求和,我使用了来自点积的示例代码和一些模糊过滤器)。
但在第一种情况下,我的代码有点慢!!!与类似的 OpenCV 代码相比,第二个代码只给了我 2 倍的速度。
我的系统(英特尔酷睿 i7 4700HQ 2.4GHz 和 Geforce GT 750m)(N46JV 华硕笔记本电脑) 我在 Windows 10 中使用 Visual Studio 2015、Cuda 8、OpenCV 3.1。
我的代码给了我结果并且逻辑上是正确的。
我的问题是我应该对我的系统有更多期望吗?
我也使用了一些 NPP 代码,但它并没有改变任何东西,它们甚至比我自己的代码慢一点(为了减少)
我之前问过一些人,这是我最后的希望!
例如求和码:
__global__ void GF3_kernel(double* oldU_temp,
int width,
int height,
double* d_partial_sum_t) {
__shared__ double L[nthreadsGF3];
//Initialize shared memory:
L[threadIdx.x] = 0;
__syncthreads();
//calculate pixel coordinates
const int tid_in = blockIdx.x * blockDim.x + threadIdx.x;
int tid_test = tid_in;
const int cacheXIndex = threadIdx.x;
//temperory sum
double temp = 0;
tid_test = tid_in;
//power random pixels of thread
while (tid_test < width * height) {
temp += oldU_temp[tid_test];
tid_test += gridDim.x * blockDim.x;
}
L[cacheXIndex] = temp;
__syncthreads();
int p_idx = blockDim.x / 2;
while (p_idx != 0) {
if (cacheXIndex < p_idx) {
L[cacheXIndex] += L[cacheXIndex + p_idx];
}
__syncthreads();
p_idx /= 2;
}
if (cacheXIndex == 0) {
d_partial_sum_t[blockIdx.x] = L[0];
}
}
内核调用将是:
/////////////////////////////////////////////////////////// sum /////////////////////////////////////////////////////////////
GF3_kernel << <gridGF3, nthreadsGF3 >> >(d_oldU_temp, width, height, d_partial_sum_t);
// copy for final summation in cpu
cudaDeviceSynchronize();
cudaMemcpy(partial_sum_t, d_partial_sum_t, gridGF3 * sizeof(double), cudaMemcpyDeviceToHost);
cudaDeviceSynchronize();
//Summation result
sum_temp = 0;
//calculate Summation
for (int j = 0; j < gridGF3; j++) {
sum_temp += partial_sum_t[j];
}
类似的东西。
你怎么看?
图像是尺寸为 390x390 像素的 1 通道图像
【问题讨论】:
-
由于(至少)一条指令——多数据模型和一些不明显的内存访问特性,GPGPU 的软件开发比常规开发复杂得多。试着写一些更简单的东西作为你的第一个例子,你应该会看到速度提高了。
-
加速很大程度上取决于您的实现,因为需要更改算法以支持并行处理。此外,当数据从 CPU 复制到 GPU 再从 GPU 复制到 CPU 时,会丢失一些时间。因此,当您处理相当大的数据集时,GPGPU 将获得回报。
-
除了所有其他说明(gpu 编程并非微不足道等)之外,您还必须处理用于测试的实际任务。例如,图像大小很重要。对于小图像,CPU 可能比 GPU 更快,因为您需要执行大量工作才能克服 gpu 的初始偏移缺陷:mcclanahoochie.com/blog/wp-content/uploads/2011/09/… 取自 mcclanahoochie.com/blog/2011/09/…
-
我知道,我只有输入数据和输出被复制。并且在减少中,我将最后一部分发送到 cpu
-
一个大问题是您使用的是双精度 - 大多数 GPU 的双精度性能非常差 - 请尝试改用
float。