c++和cuda混合编程记录(一)

本文探讨了CUDA与C++混编的可能性及挑战。通过实验对比使用类和struct的不同表现,验证了在某些情况下使用类并不会导致严重问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          最近在用cuda将RT并行化。

          很多人都说,最好使用c来写cuda,不要用类,尽量用struct代替。因为在cuda里面使用oo来套现在会有很多问题。

          我也试过,确实很多问题,之前用cpp写的光线追踪用cuda并行化过程中遇到很多问题!快要崩溃的边缘!之后把类改成了struct之后(估计我还改了其他东西-_-),居然奇迹的好了。所以心里一直有疑问,cuda真的不能和cpp一起使用嘛??不能在cuda中使用oo的思想吗??我也找过一些资料,就是说可能是和nvcc编译器有关的,很多人吐槽这个nvcc各种难用-_-(深表同意)。

         所以我决定做做实验,将oo编程思想运用到cuda中(c++和cuda混合编程),看能否复现之前遇到的那些难以解决的bug。

       

       

// CUDA-C includes
#include <cuda.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>

#define N ( 3 * 1024)


class object
{
public :
    __device__ object();
    __device__ ~object();
    __device__ virtual int hit()=0;
};
__device__ object::object()
{
   // printf("object\n");
    int x = 5;
}
__device__ object::~object()
{
    //printf("zz\n");
}
class sphere : public object
{
public:
    __device__ sphere();
    __device__ ~sphere();
    __device__ int hit();
};
__device__ sphere::sphere()
{
   // printf("ss\n");
}
__device__ int sphere::hit()
{
    return 45;
}
__device__ sphere::~sphere()
{
    printf("deconstrust\n");
}

class cube : public object
{
  public:
    __device__ cube();
    __device__ ~cube();
    __device__ int hit();
};
__device__ cube::cube()
{

}
__device__ cube::~cube()
{

}
__device__ int cube::hit()
{
    return 55;
}

__device__ int AddHit(object* o, object* t)
{
    return o->hit() + t->hit();
}

__global__ void  add(int *a , int *b , int* c , int* d)
{
     sphere* s = new sphere();
     cube* cu = new cube();
     int x =  AddHit(s,cu);
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    while( tid < N)
    {
       c[ tid ] = x;
       tid += blockDim.x * gridDim.x;
    }
}
// Main cuda function
int a[N] , b[N] , c[N];
void runCudaPart()
{
    int a[N] , b[N] , c[N];
    int *dev_a, *dev_b , *dev_c;
    int *d;
    int count = 2;

    cudaMalloc( (void**)&dev_a , N * sizeof(int ) );
    cudaMalloc( (void**)&dev_b , N * sizeof(int ) );
    cudaMalloc( (void**)&dev_c , N * sizeof(int ) );
    cudaMalloc( (void**)&d , N * sizeof(int ) );


    for(int i = 0; i < N; i++)
    {
        a[i] = -i;
        b[i] = i + 1;

    }

    cudaMemcpy( dev_a , a , N * sizeof(int) , cudaMemcpyHostToDevice);
    cudaMemcpy( dev_b , b , N * sizeof(int) , cudaMemcpyHostToDevice);

    add<<<128,128>>>( dev_a , dev_b , dev_c, d);

    cudaMemcpy( c , dev_c , N * sizeof(int) , cudaMemcpyDeviceToHost);


    int errCounts = 0;
    //显示结果
    for(int  i = 0; i < N ; i++)
    {
        printf(" %d \n",  c[i]);
    }
    cudaFree( dev_a );
    cudaFree( dev_b );
    cudaFree( dev_c );

}


int main(int argc, char *argv[])
{
//    sphere* s = new sphere();
//    int x = s->hit();
//    printf("x = %d\n",x);
//    delete s;
    runCudaPart();
}


        这份代码跑起来还是没问题的。

       奇怪,居然没问题-_-。

       先马一下,继续修改代码继续其他实验。

### CUDAC++混合编程简介 CUDA并行计算平台编程模型,允许开发者利用NVIDIA GPU的强大性能来加速应用程序。当涉及到复杂的科学计算或机器学习任务时,通常会结合C++的灵活性以及CUDA的高性能特性来进行开发。 以下是关于如何进行CUDAC++混合编程些核心概念技术要点: #### 1. 基本结构 在CUDAC++混合编程中,程序可以分为两部分:主机代码(Host Code)设备代码(Device Code)。主机代码运行于CPU上,而设备代码则运行于GPU上[^1]。 - 主机代码负责初始化数据、分配内存以及调用设备函数。 - 设备代码实现具体的并行算法逻辑。 ```cpp #include <cuda_runtime.h> #include <iostream> __global__ void addKernel(int *c, const int *a, const int *b, int size) { int i = blockIdx.x * blockDim.x + threadIdx.x; if (i < size) c[i] = a[i] + b[i]; } void runOnGpu(const std::vector<int>& h_a, const std::vector<int>& h_b, std::vector<int>& h_c) { int size = h_a.size(); int bytes = sizeof(int) * size; // Allocate device memory int* d_a, *d_b, *d_c; cudaMalloc((void**)&d_a, bytes); cudaMalloc((void**)&d_b, bytes); cudaMalloc((void**)&d_c, bytes); // Copy data from host to device cudaMemcpy(d_a, h_a.data(), bytes, cudaMemcpyHostToDevice); cudaMemcpy(d_b, h_b.data(), bytes, cudaMemcpyHostToDevice); // Launch kernel int threadsPerBlock = 256; int blocksPerGrid = (size + threadsPerBlock - 1) / threadsPerBlock; addKernel<<<blocksPerGrid, threadsPerBlock>>>(d_c, d_a, d_b, size); // Copy result back to host cudaMemcpy(h_c.data(), d_c, bytes, cudaMemcpyDeviceToHost); // Free device memory cudaFree(d_a); cudaFree(d_b); cudaFree(d_c); } ``` 上述代码展示了如何定义个简单的核函数`addKernel`,并通过CUDA API管理内存传输执行流程。 --- #### 2. 数据传递机制 为了使主机设备之间的通信更加高效,需注意以下几个方面: - **显存分配**:使用`cudaMalloc`为设备端变量分配空间。 - **数据复制**:通过`cudaMemcpy`完成主机到设备的数据拷贝操作。 - **同步控制**:可以通过`cudaDeviceSynchronize()`确保所有线程都已完成当前工作后再继续后续处理。 这些步骤对于优化整体性能至关重要[^3]。 --- #### 3. 并行化策略设计 编写高效的CUDA程序依赖合理的并行化方案设计。例如,在矩阵乘法运算中可以选择不同的分块方式以减少全局存储器访问次数从而提升效率[^2]。 --- #### 4. 工具链支持 构建包含CUDA扩展名`.cu`文件的应用项目需要特定编译工具链的支持。常用的有NVCC(NVIDIA Cuda Compiler),它能够解析标准C/C++源码同时也理解专属于GPU架构下的指令集语法。 --- #### 5. 调试技巧 由于异构环境增加了复杂度,因此掌握有效的调试方法尤为重要。推荐采用Nsight系列工具或者Visual Studio集成插件辅助定位潜在错误点。 --- ### 总结 综上所述,成功实施CUDA-C++联合解决方案不仅要求扎实的基础理论功底还需要不断实践积累经验教训才能达到理想效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值