CUDA 内核函数

2024-08-29 07:28
文章标签 函数 内核 cuda

本文主要是介绍CUDA 内核函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、简介
  • 二、实现代码
  • 三、实现效果
  • 参考资料

一、简介

CUDA为我们提供了可扩展的编程模型:它的核心是三个关键的抽象——线程组的层次结构、共享内存和阻塞同步——它们只是作为一组最小的语言扩展暴露给外部使用人员。这些抽象提供细粒度数据并行性和线程并行性,嵌套在粗粒度数据并行性和任务并行性中。它们引导程序员将问题划分为可以由线程块独立并行解决的粗子问题,并将每个子问题划分为可以由线程块内的所有线程并行协作解决的细子问题。这种分解通过允许线程在解决每个子问题时进行协作来保持语言的表达性,同时支持自动可伸缩性。实际上,每个线程块都可以在GPU内任何可用的多处理器上调度,以任何顺序,并发或顺序,以便编译后的CUDA程序可以在下图所示的任意数量的多处理器上执行,并且只有运行时系统需要知道物理多处理器计数。这种可扩展的编程模型允许GPU架构通过简单地扩展多处理器和内存分区的数量来跨越广泛的市场范围:从高性能爱好者的GeForce GPU和专业的Quadro和Tesla计算产品到各种廉价的主流GeForce GPU(参见支持cuda的GPU以获得所有支持cuda的GPU的列表)。

GPU是围绕一组流多处理器(SMs)构建的(详见硬件实现)。一个多线程程序被分割成相互独立执行的线程块,这样多处理器的GPU会比少处理器的GPU在更短的时间内自动执行程序。

OK,说了这么多也只是说了一些CUDA的设计理念,对于我们真正使用上来讲,还是要聚焦于代码方面。我们首先要明确一个概念CUDA c++扩展了c++语言,它允许我们定义CUDA c++函数,只不过这种函数通过供多个线程使用,称为内核函数,当调用时,它由N个不同的CUDA线程并行执行N次,而不是像常规的c++函数那样只执行一次。

使用方式:内核是使用__global__声明说明符定义的,对于给定的内核调用,执行该内核的CUDA线程数是使用新的<<<…>>>执行配置语法(参见c++语言扩展)。每个执行内核的线程都有一个唯一的线程ID,可以通过内置变量在内核中访问。这里我们举一个简单的例子。

二、实现代码

#include <iostream>
#include <vector>#include <cuda_runtime.h>
#include <device_launch_parameters.h>//定义内核函数
__global__ void VecAdd(float* A, float* B, float* C)
{int i = threadIdx.x;C[i] = A[i] + B[i];
}int main()
{const int N = 1024; // 假设我们处理1024个元素的向量  size_t size = N * sizeof(float);// 1. 分配主机内存std::vector<float> dataA(size), dataB(size), dataC(size);for (int i = 0; i < N; ++i) {dataA[i] = rand() / (float)RAND_MAX;dataB[i] = rand() / (float)RAND_MAX;}float* h_A = dataA.data();float* h_B = dataB.data();float* h_C = dataC.data();// 2. 分配设备内存  float* d_A, * d_B, * d_C;cudaMalloc(&d_A, size);cudaMalloc(&d_B, size);cudaMalloc(&d_C, size);// 3. 复制数据到设备  cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);// 4. 启动内核  VecAdd <<<1, N >> > (d_A, d_B, d_C);      //这里我们只使用一个线程块,N个线程// 等待GPU完成工作  cudaDeviceSynchronize();// 5. 复制结果回主机  cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);// 6. 验证结果(这里只是打印第一个元素作为示例)  std::cout << "A[0] = " << h_A[0] << std::endl << "B[0] = " << h_B[0] << std::endl<< "C[0] = " << h_C[0] << std::endl;// 7. 释放资源  cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);
}

三、实现效果

在这里插入图片描述

参考资料

[1]https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html

这篇关于CUDA 内核函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1117225

相关文章

新特性抢先看! Ubuntu 25.04 Beta 发布:Linux 6.14 内核

《新特性抢先看!Ubuntu25.04Beta发布:Linux6.14内核》Canonical公司近日发布了Ubuntu25.04Beta版,这一版本被赋予了一个活泼的代号——“Plu... Canonical 昨日(3 月 27 日)放出了 Beta 版 Ubuntu 25.04 系统镜像,代号“Pluc

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

kotlin的函数forEach示例详解

《kotlin的函数forEach示例详解》在Kotlin中,forEach是一个高阶函数,用于遍历集合中的每个元素并对其执行指定的操作,它的核心特点是简洁、函数式,适用于需要遍历集合且无需返回值的场... 目录一、基本用法1️⃣ 遍历集合2️⃣ 遍历数组3️⃣ 遍历 Map二、与 for 循环的区别三、高

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

MySQL中COALESCE函数示例详解

《MySQL中COALESCE函数示例详解》COALESCE是一个功能强大且常用的SQL函数,主要用来处理NULL值和实现灵活的值选择策略,能够使查询逻辑更清晰、简洁,:本文主要介绍MySQL中C... 目录语法示例1. 替换 NULL 值2. 用于字段默认值3. 多列优先级4. 结合聚合函数注意事项总结C

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

golang panic 函数用法示例详解

《golangpanic函数用法示例详解》在Go语言中,panic用于触发不可恢复的错误,终止函数执行并逐层向上触发defer,最终若未被recover捕获,程序会崩溃,recover用于在def... 目录1. panic 的作用2. 基本用法3. recover 的使用规则4. 错误处理建议5. 常见错