当前位置: 首页 > news >正文

GPU编程

GPU编程既要考虑CPU硬件也要考虑GPU硬件。这种编程称为异构编程

代码从CPU上开始执行,遇到需要大量并行化的部分,再到GPU上并行,然后将结果返还给CPU再进行其他可能的计算。

CPU上的向量加法

  • 开辟内存空间,
  • 初始化两个向量,
  • 循环相加,或者使用向量化的相加
  • 释放内存

这种计算效率很受带宽限制,例如下面代码要计算长度为100万的两向量加法

#include <iostream>
int main(void) {
int N = 1<<20; // 1M elements
float *x = new float[N]; // Allocate memory
float *y = new float[N];
// initialize x and y on the CPU
for (int i = 0; i < N; i++) {x[i] = 1.0f; y[i] = 2.0f;
}// Run on 1M elements on the CPU
add(N, x, y);// Free memory
delete [] x; delete [] y;
return 0;
}

GPU上的向量加法

在GPU上执行的函数称为内核函数(kernel),由CPU调用内核函数

  • GPU上开辟内存空间(显存)
  • 将数据复制到GPU上
  • 执行内核函数
  • 等待计算
  • 将结果返还给CPU

GPU串行计算向量加法

float *x = new float[N];
float *y = new float[N];
int size = N*sizeof(float);
float *d_x, *d_y; // device copies of x y
cudaMalloc((void **)&d_x, size);//GPU上开辟内存
cudaMalloc((void **)&d_y, size);//GPU上开辟内存
cudaMemcpy(d_x, x, size, cudaMemcpyHostToDevice);//CPU到GPU转移数据
cudaMemcpy(d_y, y, size, cudaMemcpyHostToDevice);//CPU到GPU转移数据
// Run kernel on GPU
add<<<1,1>>>(N, d_x, d_y);//调用内核代码,<<<1,1>>>表示使用单线程计算
// Copy result back to host
cudaMemcpy(y, d_y, size, cudaMemcpyDeviceToHost);//将结果返还给CPU
// Free memory
cudaFree(d_x); cudaFree(d_y);
delete [] x; delete [] y;// GPU function to add two vectors
__global__ //添加关键字表示以下函数为内核函数
void add(int n, float *x, float *y) {
for (int i = 0; i < n; i++)
y[i] = x[i] + y[i];
}

如果想要利用并行性计算提升计算速度,则要使用多个线程同时计算。需要改写kernel函数

// GPU function to add two vectors
__global__
void add(int n, float *x, float *y) {
int index = threadIdx.x;//CUDA线程的索引
y[index] = x[index] + y[index];
}add<<<1,256>>>(N, d_x, d_y);//使用一个线程块中的256个线程进行计算

相关文章:

  • 【机器学习】 朴素贝叶斯算法:原理、实例应用(文档分类预测)
  • 使用validator实现枚举类型校验
  • MacOS Ventura 13 优化配置(ARM架构新手向导)
  • VSCode 好用的插件分享
  • 【多线程 - 04、Join 方法与 wait 方法】
  • postman调用接口报{“detail“:“Method \“DELETE\“ not allowed.“}错误, 解决记录
  • Spark3.0中的AOE、DPP和Hint增强
  • C++知识点梳理:移动语意、右值
  • js实现对象数组去重
  • kali命令行下python多版本切换
  • 2023年数维杯国际大学生数学建模挑战赛
  • js设置图片放大缩小拖动
  • [工业自动化-19]:西门子S7-15xxx编程 - 软件编程 - PLC程序块、组织块OB与PLC多线程原理、OB、FC、FB、DB
  • STM32与RTOS的整合:实时操作系统在嵌入式开发中的应用
  • 自定义Graph Component:1.2-其它Tokenizer具体实现
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【前端学习】-粗谈选择器
  • Computed property XXX was assigned to but it has no setter
  • Elasticsearch 参考指南(升级前重新索引)
  • ESLint简单操作
  • HashMap剖析之内部结构
  • Laravel Telescope:优雅的应用调试工具
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • sublime配置文件
  • Twitter赢在开放,三年创造奇迹
  • vue的全局变量和全局拦截请求器
  • vue学习系列(二)vue-cli
  • yii2权限控制rbac之rule详细讲解
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 三栏布局总结
  • 最近的计划
  • elasticsearch-head插件安装
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #stm32驱动外设模块总结w5500模块
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (12)Linux 常见的三种进程状态
  • (3)(3.5) 遥测无线电区域条例
  • (JS基础)String 类型
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (备忘)Java Map 遍历
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (学习日记)2024.01.19
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .CSS-hover 的解释
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET开源项目介绍及资源推荐:数据持久层
  • .net中的Queue和Stack
  • /dev下添加设备节点的方法步骤(通过device_create)
  • /etc/shadow字段详解