Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C++;和库达 我刚刚开始使用CUDA,想知道如何最好地使用C++的“强”>主机边 API。我最初倾向于使用内联函数和方法来包装任何C API,在错误返回时添加异常,以便与我的其余代码很好地融合。我已经简要介绍了推力,但这似乎是一个更高层次的东西,并且没有包装您可能需要使用的其他API_C++_Cuda - Fatal编程技术网

使用C++;和库达 我刚刚开始使用CUDA,想知道如何最好地使用C++的“强”>主机边 API。我最初倾向于使用内联函数和方法来包装任何C API,在错误返回时添加异常,以便与我的其余代码很好地融合。我已经简要介绍了推力,但这似乎是一个更高层次的东西,并且没有包装您可能需要使用的其他API

使用C++;和库达 我刚刚开始使用CUDA,想知道如何最好地使用C++的“强”>主机边 API。我最初倾向于使用内联函数和方法来包装任何C API,在错误返回时添加异常,以便与我的其余代码很好地融合。我已经简要介绍了推力,但这似乎是一个更高层次的东西,并且没有包装您可能需要使用的其他API,c++,cuda,C++,Cuda,是否有我缺少的现有包装器,或者是否有充分的理由直接使用我忽略的C API 更新:我确实找到了一个与我所要查找的内容类似的库。它比我想要的更抽象,所以我可能不会使用它,但我把这里作为参考,以防其他人有同样的问题 我的答案绝对不完整。根据我在研究CUDA时的记忆,可以在这些内核中运行的代码类型非常有限。分配给每个内核的内存空间非常小,因此,不能有大的堆栈、堆分配的对象和C++所具有的所有好东西,这使得C++对于CUDA的目的几乎没有用。因此,即使有包装器,由于您可以这样做的限制,使用它也不实际。然而

是否有我缺少的现有包装器,或者是否有充分的理由直接使用我忽略的C API


更新:我确实找到了一个与我所要查找的内容类似的库。它比我想要的更抽象,所以我可能不会使用它,但我把这里作为参考,以防其他人有同样的问题

我的答案绝对不完整。根据我在研究CUDA时的记忆,可以在这些内核中运行的代码类型非常有限。分配给每个内核的内存空间非常小,因此,不能有大的堆栈、堆分配的对象和C++所具有的所有好东西,这使得C++对于CUDA的目的几乎没有用。因此,即使有包装器,由于您可以这样做的限制,使用它也不实际。然而,C++语言中的C习语在最低层次上的替换并不总是可行的。例如,执行完整的RAII通常效率低下:在GPU上初始化阵列的速度可能比在CPU上慢得多,而且通常可以使用“单元化”模式来设计内核,以取代这一昂贵的步骤。您可以在C++类中管理这种类型的东西,但是IMO在一个额外的C层中安全一些,没有人期望所有的东西都被很好地撕毁。如果您想做的只是在错误上抛出异常,请考虑使用.< /P> 例如:

#include <thrust/system_error.h>

void my_cudaMalloc_wrapper(void **devPtr, size_t size)
{
  cudaError_t error = cudaMalloc(devPtr, size);
  if(error != cudaSuccess)
  {
    throw thrust::system_error(error, thrust::cuda_category());
  }
}

CUDA调用通常与内核调用密切相关。例如,您可以使用
cudamaloc()
分配一些内存,然后在该内存上运行内核。内核本身、调用内核的代码(使用三个括号语法)和设置纹理等资源的代码都必须位于.cu文件中

因此,我认为最好只创建小型C风格库,将与一个内核(或几个紧密相关的内核)相关的功能封装起来。然后,如果需要,C型库可以被封装在C++接口中。
因此,例如,C风格库可能有一个设置内核运行所需的所有资源的
init()
调用,一个调用一个或多个内核的
compute()
调用和一个释放所有资源的
deinit()
调用。然后,如果需要,可以在其构造函数中调用< >代码>(或)代码>在其构造函数中调用< >代码> DENITI](<代码>),并用检查返回值的方法包装<代码>计算机()/CULL调用,并引发异常。< / P>我正在寻找一个主机侧包装器,包装调用如“代码> CUDAMOLC/<代码>等C++。(或者更确切地说,OO),对GPU代码不是很有用,但不是因为您提到的原因。有CUDA函数可以调整内核可用的堆栈空间和堆空间。GPU上面向对象编程的真正问题是它不能方便地提供对内存访问模式的细粒度控制。我更多考虑的是函数在出错时抛出异常,而不是返回代码(可能这就是您提到的C层?)。RAII实际上不需要初始化值,只要数组中有垃圾标量是可以的,我就可以使用它。通过“完整RAII”我的意思是,没有任何公开的垃圾值。显然,即使在正常的C++中,有时你也会牺牲性能,但是我喜欢把它保持在最低限度(我认为这是一个很重要的问题)。就你所说的,正常的“弱RAII”而言。已经足够使这些安全了。RAII和设计使存在的资源总是被初始化是不同的事情。std::vector在size()和capacity()之间有潜在的未初始化内存,和std::unique_ptr可以有一个指向未初始化内存的有效分配。这两个配置都可以像未初始化设备内存一样轻松地攻击自己。谢谢,我知道如何实现它,我只是不想重新发明轮子。您的解决方案确实增加了对推力的依赖,这似乎并不必要,我宁愿自己实现一个简单的std::runtime_error派生类。这里有没有充分的理由依赖于推力?我可以看到封装内核和相关类的需要,特别是因为.cu的需要。但是为什么还要另一个C风格的层?为什么不使用具有良好异常安全性的类?因为内核和纹理不能成为cla的成员SS,我想,对我来说,构建一个C风格的界面来展示这些资源似乎更自然。这样,你就只能在.CPP文件中而不是在.Cu文件中使用。但是,既然你可以在一个.Cu文件中拥有C++类,并且从类中调用内核,那么我的方法可能就不必要复杂了。有时候,能写DL是很好的。对于CUDA功能,这样应用程序对CUDA的依赖性就本地化到DLL。然后,DLL暴露纯C风格的接口也可能更自然。另外两件事要注意……首先,尽管Cube文件支持C++特性,但显然您可以做些什么。例如,我已经听到了。模板存在一些问题,因此无法在.cu文件中使用Boost。其次,.cu文件的编译速度很慢,因此如果只保留严格必须在.cu文件中的功能,开发周期可能会更快。这可以通过在简单的C风格接口中公开.cu功能并保留
#include <iostream>

void foo()
{
  int *ptr = 0;
  size_t n = 13;
  try
  {
    my_cudaMalloc_wrapper(&ptr, n);
  }
  catch(std::runtime_error &error)
  {
    std::cerr << "Uh oh: " << error.what() << std::endl;
  }
}