SugarAnnie 2019-05-28 19:47 采纳率: 0%
浏览 604

调用CUDA API使用GPU运算一个JuliaSet花费的时间比在CPU上多

我用的是《GPU高性能编程CUDA实战》第四章最后的一个例子,在CPU上花费的时间700+ms,在GPU上花费的时间是800+ms

// CPU版本代码

void kernel(unsigned char * ptr) {
    for (size_t y = 0; y < DIM; y++) for (size_t x = 0; x < DIM; x++)
    {
        int offset = x + y*DIM;
        int juliaValue = julia(x, y);

        ptr[offset * 4 + 0] = 255 * juliaValue;
        ptr[offset * 4 + 1] = 0;
        ptr[offset * 4 + 2] = 0;
        ptr[offset * 4 + 3] = 255;
    }
}

int main(void) {

    clock_t start, finish;
    double totaltime;
    start = clock();

    CPUBitmap bitmap(DIM, DIM);
    unsigned char *ptr = bitmap.get_ptr();

    kernel(ptr);

    finish = clock();
    totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("time : %fs\n", float(totaltime));

    bitmap.display_and_exit();

    return 0;
}


// GPU版本代码

#define DIM 1000

struct cuComplex
{
    float r;
    float i;
    __device__ cuComplex(float a, float b) : r(a), i(b) {}
    __device__ float magnitude2(void) { return r * r + i * i; }
    __device__ cuComplex operator*(const cuComplex& a) { return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i); }
    __device__ cuComplex operator+(const cuComplex& a) { return cuComplex(r + a.r, i + a.i); }
};

__device__ int julia(int x, int y) {
    const float scale = 1.5;
    float jx = scale * (float)(DIM / 2 - x) / (DIM / 2);
    float jy = scale * (float)(DIM / 2 - y) / (DIM / 2);

    cuComplex c(-0.8, 0.156);
    cuComplex a(jx, jy);

    for (size_t i = 0; i < 200; i++)
    {
        a = a*a + c;
        if (a.magnitude2() > 1000) return 0;
    }

    return 1;
}

__global__ void kernel(unsigned char * ptr) {
    // 将threadIdx/BlockIdx映射到像素位置
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y*gridDim.x;

    // 计算对应位置上的值
    int juliaValue = julia(x, y);
    ptr[offset * 4 + 0] = 255 * juliaValue;
    ptr[offset * 4 + 1] = 0;
    ptr[offset * 4 + 2] = 0;
    ptr[offset * 4 + 3] = 255;
}

int main(void) {

    clock_t start, finish;
    double totaltime;
    start = clock();

    CPUBitmap bitmap(DIM, DIM);

    unsigned char *dev_bitmap;
    cudaMalloc((void **)&dev_bitmap, bitmap.image_size());

    dim3 grid(DIM, DIM);
    kernel<< <grid, 1 >> >(dev_bitmap);

    cudaMemcpy(bitmap.get_ptr(), dev_bitmap, bitmap.image_size(), cudaMemcpyDeviceToHost);

    cudaFree(dev_bitmap);

    finish = clock();
    totaltime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("time : %fs\n", float(totaltime));

    bitmap.display_and_exit();

    return 0;
}

运行结果是这张图片
图片说明
熟悉CUDA编程的大神能否解释一下为什么使用GPU并行计算花费的时间反而跟多?

配置是i7-8700 + GTX1060 6G

  • 写回答

1条回答 默认 最新

  • threenewbee 2019-05-28 21:36
    关注

    julia是哪里的函数,对于gpu来说,调用函数开销很大,如果是调用主机上的函数,开销更大。

    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?