CUDA(2)

cudaMalloc
函数告诉CUDA运行时在设备上分配内存。
函数使用限制

 1. 可以将cudaMalloc()分配的指针传递给在设备上执行的函数。
 2. 可以在设备代码中使用cudaMalloc()分配的指针进行内存读/写操作。
 3. 可以将cudaMalloc()分配的指针传递给在主机上执行的函数。
 4. 不能在主机代码中使用cudaMalloc()分配的指针进行内存读/写操作。
 5. 不能使用标准C的free()函数来释放cudaMalloc()分配的内存;要释放cudaMalloc()分配的内存,需要调用cudaFree()。

设备指针的使用方式与标准C中指针的使用方式完全一样。主机指针只能访问主机代码中的内存,而设备指针也只能访问设备代码中的内存。 在主机代码中可以通过调用cudaMemcpy()来访问设备上的内存。

内置变量

CUDA运行时允许启动一个二维线程格,并且线程格中的每个线程块都是一个三维的线程数组。

 1. blockDim  线程块中的线程数量 。
 2. gridDim   线程格中线程块的数量。
 3. blockIdx  当前执行设备代码的线程块的索引。
 4. threadIdx 当前执行设备代码的线程索引。

对于使用多个线程块并且每个线程块中包含多个线程。计算线程索引为

int tid = threadIdx.x+blockIdx.x*blockDim.x

多CPU时,tid每次增加的是CPU的数量。在GPU实现中,将并行线程的数量作为处理器的数量。

tid += blockDim.x*gridDim.x;

CUDA将每个线程并行执行,需要计算每个并行线程的初始索引和递增的量值。递增的步长为线程格中正在运行的线程数量。

共享内存、常量

__shared__添加到变量声明中,这将使这个变量驻留在共享内存中。CUDA C编译器对共享内存中的变量与普通变量将分别采取不同的处理方式。共享内存存在GPU上,因此访问共享内存的速度高于访问普通的系统内存。
__shared__ 共享变量是block中所有线程共享的变量。共享变量的声明可以在kernel内部,也可以作为全局变量。如果共享变量是在kernel中声明的,其作用域就是kernel内,否则对所有kernel有效。
如果共享变量的大小在声明时不指定 :

extern __shared__ int  title[];

常量内存用于保存在核函数执行期间不会发生变化的数据。CUDA对常量内存采取了不同于标准全局内存的处理方式。在某些情况下,用常量内存来替换全局内存能有效地减少内存带宽。要使用常量内存,需在变量前面加上__constant__关键字。

线程 、线程组

GPU上的线程调度方式与CPU有很大不同。CPU的调度算法包含优先级、时间片等。GPU上所有线程机会均等,线程状态只有等待资源和执行两种状态,如果资源未就绪,那么就等待;一旦就绪,立即执行。

当GPU资源很充裕时,所有线程都是并发执行的,这样加速效果很接近理论加速比;而GPU资源少于总线程个数时,有一部分线程就会等待前面执行的线程释放资源,从而变为串行化执行。

块并行相当于CPU多进程的情况。CUDA的线程块将一组线程组织到一起,共同分配一部分资源,然后内部调度执行。线程块与线程块之间没有关系。

线程并行和线程块并行的区别:

线程并行是细粒度并行,调度效率高;块并行是粗粒度并行,每次调度都要重新分配资源,有时资源只有一份,那么所有线程块都只能排成一队,串行执行。
设备信息
//获得CUDA设备个数
int count;
HANDLE_ERROR(cudaGetDeviceCount(&count));
//迭代查询每个设备的相关信息。cudaDeviceProp结构包含了设备的相关信息
cudaDeviceProp prop;
for(int i=0;i<count;i++)
{
    HANDLE_ERROR(cudaGetDeviceProperties(&prop,i));
}

// 选择满足条件的CUDA设备
cudaDeviceProp prop;
int dev;
memset(&prop,0,sizeof(cudaDeviceProp));
prop.major=1;
prop.minor=3;
HANDLE_ERROR(cudaChooseDevice(&dev,&prop));
kernel 函数

__device__ 修饰符表示代码将在GPU而不是host上运行。声明为__device__ 的函数只能被其他__device____global__ 修饰的函数调用。

线程同步
//对线程块中的线程进行同步
__syncthreads();

该函数确保线程块中每个线程都执行完__syncthreads()之前的语句后,才会执行下一条语句。
注意,将__syncthreads()放在if的结构中可能导致程序失败。这种情况下,可能会导致线程发散(某些线程需要执行一条指令,而其他线程不需要执行)。CUDA架构确保线程块中的每个线程都执行了

__syncthreads();

否则没有任何线程可以执行之后的语句。在线程发散的情况中,一些线程永远都无法执行__syncthreads() ,硬件将这些线程保持等待,一直等下去。

TX2是一款由NVIDIA推出的超级计算开发板,它拥有强大的GPU处理能力,可以运行深度学习和计算机视觉相关的应用程序。而在使用TX2进行开发时,有时候可能会出现“TX2 CUDA false”的问题。这个问题一般是由于CUDA安装不正确或者版本不匹配所引起的。 在解决这个问题之前,我们需要先了解一下CUDA是什么。CUDA是NVIDIA推出的一种并行计算平台和编程模型,它允许开发者在GPU上运行复杂的计算任务,大大提高了计算性能。在TX2中使用CUDA,就可以让开发者更加高效地实现深度学习和计算机视觉应用。 为了解决“TX2 CUDA false”的问题,我们可以采取如下步骤: 1.检查CUDA是否正确安装:首先需要检查CUDA是否正确安装,并且版本是否匹配。可以通过命令行运行“nvcc --version”来检查CUDA版本信息。 2.检查CUDA环境变量设置:如果CUDA版本信息正确,那么需要进一步检查CUDA环境变量的设置。可以通过命令行运行“echo $LD_LIBRARY_PATH”来查看环境变量是否正确。 3.卸载并重新安装CUDA:如果以上两个步骤都没有解决问题,那么可能需要卸载并重新安装CUDA。在重新安装时,需要确保选择正确的版本,并仔细遵循安装指南。 总之,解决“TX2 CUDA false”的问题需要仔细检查CUDA环境的设置,并确保正确安装和配置。只有这样,才能保证TX2的GPU处理能力得到最大的发挥。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值