CUDA 学习记录

1.关于volatile:

对于文章中这个函数,

__global__ void reduceUnrollWarps8 (int *g_idata, int *g_odata, unsigned int n)
{// set thread IDunsigned int tid = threadIdx.x;unsigned int idx = blockIdx.x * blockDim.x * 8 + threadIdx.x;// convert global data pointer to the local pointer of this blockint *idata = g_idata + blockIdx.x * blockDim.x * 8;// unrolling 8if (idx + 7 * blockDim.x < n){int a1 = g_idata[idx];int a2 = g_idata[idx + blockDim.x];int a3 = g_idata[idx + 2 * blockDim.x];int a4 = g_idata[idx + 3 * blockDim.x];int b1 = g_idata[idx + 4 * blockDim.x];int b2 = g_idata[idx + 5 * blockDim.x];int b3 = g_idata[idx + 6 * blockDim.x];int b4 = g_idata[idx + 7 * blockDim.x];g_idata[idx] = a1 + a2 + a3 + a4 + b1 + b2 + b3 + b4;}__syncthreads();// in-place reduction in global memoryfor (int stride = blockDim.x / 2; stride > 32; stride >>= 1){if (tid < stride){idata[tid] += idata[tid + stride];}// synchronize within threadblock__syncthreads();}// unrolling warpif (tid < 32){volatile int *vmem = idata;vmem[tid] += vmem[tid + 32];vmem[tid] += vmem[tid + 16];vmem[tid] += vmem[tid +  8];vmem[tid] += vmem[tid +  4];vmem[tid] += vmem[tid +  2];vmem[tid] += vmem[tid +  1];}// write result for this block to global memif (tid == 0) g_odata[blockIdx.x] = idata[0];
}

在  //unrolling wrap 之前的for循环完成后,只剩下idata[0] 到 idata[63](共64个元素)的数据还没有进行加和。

之前的疑问是 最后的if语句块内为什么会完成这个操作而不出问题:

因为一个线程束内的线程会进行同步,所以if里的语句是,所有线程执行第一条语句,都执行完了,再执行第二条语句。

然后关于volitale ,大家都说是禁止编译器优化,我的理解是:

如果没有volatile,各个线程写寄存器的时候是有同步的,从寄存器写到共享内存是没有同步的。(不过在我这里,去掉volatile结果也是对的。。。)

2.关于延迟隐藏

目前个人理解就是让一个线程尽可能多做事。

3.关于如何获得最大线程束 

参考:【精选】CUDA编程:笔记2_线程束_longlongqin的博客-CSDN博客

little法则给出了下面的计算公式"所需线程束 = 延迟 × 吞吐量 

带宽:一般指的是理论峰值,最大每个时钟周期能执行多少个指令;

吞吐量:是指实际操作过程中每分钟处理多少个指令。

每次想到还是看书吧。 

一个WRAP访存周期是T,刚好是Wrap处理指令时间周期t的K倍,只需要K个wrap就能隐藏访存带来的延迟。

得到最大线程束数量还要减少分支

4.选择合适的网格和块:

有个工具包(同学说不能使了,但是应该也提供了别的方法)。

4.什么是事务内存

参考:初识事务内存(Transactional Memory) - 知乎

个人理解:比u锁更好的具有原子性的互斥手段。 

5.在GPU上只有内存加载操作可以被缓存,内存存储操作不能被缓存。

内存加载操作:从全局内存或其他内存读数据加载到寄存器或缓存中。

内存存储操作:将数据从寄存器或缓存写入到内存

线程加载数据时,如果缓存中有数据,可以直接从缓存中加载。而存储操作通常不能被缓存,因为要保证数据的一致性,必须及时更新内存中的数据,而不能依赖于缓存。

6.对于固定内存和零拷贝内存

当传输大数据时,使用固定内存:cudaError_t cudaMallocHost(void **devPtr, size_t count);

cudaError_t cudaFreeHost(void *ptr);

如果想要共享主机和设备端的少量数据,使用零拷贝内存:

cudaErroer_t cudaHostAlloc(void **pHost, size_t count, unsigned int flags);

cudaFreeHost()

使用下列函数获取映射到固定内存的设备指针:

cudaError_t cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags);

    // part 2: using zerocopy memory for array A and B// allocate zerocpy memoryCHECK(cudaHostAlloc((void **)&h_A, nBytes, cudaHostAllocMapped));CHECK(cudaHostAlloc((void **)&h_B, nBytes, cudaHostAllocMapped));// initialize data at host sideinitialData(h_A, nElem);initialData(h_B, nElem);memset(hostRef, 0, nBytes);memset(gpuRef,  0, nBytes);// pass the pointer to deviceCHECK(cudaHostGetDevicePointer((void **)&d_A, (void *)h_A, 0));CHECK(cudaHostGetDevicePointer((void **)&d_B, (void *)h_B, 0));// add at host side for result checkssumArraysOnHost(h_A, h_B, hostRef, nElem);// execute kernel with zero copy memorysumArraysZeroCopy<<<grid, block>>>(d_A, d_B, d_C, nElem);// copy kernel result back to host sideCHECK(cudaMemcpy(gpuRef, d_C, nBytes, cudaMemcpyDeviceToHost));// check device resultscheckResult(hostRef, gpuRef, nElem);// free  memoryCHECK(cudaFree(d_C));CHECK(cudaFreeHost(h_A));CHECK(cudaFreeHost(h_B));

有了虚拟内存寻址(UVA)后,由cudaHostAlloc()分配的固定主机内存具有相同的主机和设备指针,可以将返回的指针直接传递给核函数:

cudaHostAlloc((void **)&h_A, nBytes, cudaHostAllocMapped);
cudaHostAlloc((void **)&h_B, nBytes, cudaHostAllocMapped);initialData(h_A, nElem);
initialData(h_B, nElem);sumArrayZeroCopy<<<grid, block>>>(h_A, h_B, d_C, nElem);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/112258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统:线程同步和调度

文章目录 线程同步和调度一、实验目的二、实验要求与内容、过程与结果 系列文章 线程同步和调度 一、实验目的 通过创建线程、分配线程优先级和终止线程的程序设计和调试操作&#xff0c;进一步熟悉操作系统的线程概念&#xff0c;理解Windows 2000线程的生命周期。 通过对事…

18-spring 事务

文章目录 1. xml和注解配置方式的对象2.spring事务传播特性3. 注解事务的初始化流程4. 创建事务信息流程图5. 事务回滚流程图1. xml和注解配置方式的对象 2.spring事务传播特性 事务传播行为类型说明PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事…

RHEL 8.6 Kubespray 1.23.0 install kubernetes v1.27.5

文章目录 1. 预备条件2. download01 节点 安装 dockerdownload01 节点 介质下载下载 bastion01节点配置 yum 源bastion01 节点安装 docker5. 安装 docker insecure registrybastion01 部署 nginx 与 镜像入库13.1 配置 config.sh13.2 配置 setup-docker.sh13.3 配置 start-ngin…

Unity中Shader实现UI流光效果

文章目录 前言一、实现思路1&#xff1a;1、采集两张贴图&#xff0c;一张是主纹理&#xff0c;一张是扫光纹理2、在 v2f 定义一个二维变量 “uv2” 来存放 uv 偏移后的值3、在顶点着色器中&#xff0c;仿照之前的 uv 流动效果,与 _Time相乘后存放于 uv2 中4、最后&#xff0c;…

任务分配问题(回溯法)

算法设计 问题描述 有n&#xff08;n≥1&#xff09;个任务需要分配给n个人执行&#xff0c;每个任务只能分配给一个人&#xff0c;每个人只能执行一个任务。 第i个人执行第j个任务的成本是c[i][j]&#xff08;1≤i&#xff0c;j≤n&#xff09;。求出总成本最小的分配方案 …

【JVM】synchronized与锁升级

文章目录 1. synchronized锁优化背景2. synchronized锁性能优化过程2.1 java5以前2.2 monitor锁2.3 java6开始 3. 无锁4. 偏向锁4.1 背景4.2 理论落地4.3 技术实现4.4 偏向锁的撤销4.5 题外话 5. 轻量级锁5.1 轻量级锁的加锁5.2 轻量级锁的释放5.3 锁升级 6. 重量级锁7. 锁升级…

springweb+vue前后端分离开发,集成部署

背景&#xff1a; 在自己做测试的时候&#xff0c;由于需要项目和项目的前端页面使用同样接口访问&#xff0c;所以需要将前端代码部署到后端项目下。前端采用vue&#xff0c;后端采用springboot。 首先时建立一个vue项目&#xff0c;这个可以参照网上的案例&#xff0c;创建方…

Node.js的安装

直接在浏览器中搜索Node.js即可 打开下载好的文件 验证是否安装成功 在cmd中输入 node -v&#xff0c;若结果为版本号那就是成功的 环境配置 配置全局模块所在的路径缓存cache的路径 在安装目录中新建两个文件夹&#xff0c;文件夹名为:node_cache和node_global 输…

C++之this指针

前言 C中对象模型和this指针是面向对象编程中的重要概念。对象模型描述了对象在内存中的布局和行为&#xff0c;包括成员变量、成员函数的存储方式和访问权限。this指针是一个隐含的指针&#xff0c;指向当前对象的地址&#xff0c;用于在成员函数中引用当前对象的成员变量和成…

搭建伪分布式Hadoop

文章目录 一、Hadoop部署模式&#xff08;一&#xff09;独立模式&#xff08;二&#xff09;伪分布式模式&#xff08;三&#xff09;完全分布式模式 二、搭建伪分布式Hadoop&#xff08;一&#xff09;登录虚拟机&#xff08;二&#xff09;上传安装包&#xff08;三&#xf…

VMware Workstation里面安装ubuntu20.04的流程

文章目录 前言一、获取 desktop ubuntu20.04 安装镜像二、VMware Workstation下安装ubuntu20.041. VMware Workstation 创建一个新的虚拟机2. ubuntu20.04的安装过程3. 登录ubuntu20.044. 移除 ubuntu20.04 安装镜像总结参考资料前言 本文主要介绍如何在PC上的虚拟机(VMware W…

WordPress SMTP邮件发送插件 Easy WP SMTP

Easy WP SMTP是一款 WordPress 邮件发送插件&#xff0c;WordPress 中经常用到邮件发送&#xff0c;包括新注册用户的邮件通知、找回密码通知、评论回复通知等。因为云服务器默认不启用 SMTP功能&#xff0c;所以需要安装 SMTP插件来解决这个问题。 SMTP 主机&#xff1a;smtp.…

javascript/python 笔记: folium feature group自动切换

1 python部分 python部分只能是静态的结果 1.1 导入库 import folium import math 1.2 数据 cell_lst表示基站位置&#xff0c;location_lst表示 用户实际位置&#xff08;均为伪数据&#xff09; cell_lst[[1.341505, 103.682498],[1.342751, 103.679604],[1.341505, 10…

YCSB and TPC-C on MySQL(避免重复load)

一、编译安装MySQL 下载mysql5.7.28源码 https://downloads.mysql.com/archives/community/ Select Operating System 选择 Source Code Select OS version 选择 All Operating Systems 选择带有boost的版本 安装系统包 apt -y install make cmake gcc g perl bison libai…

虹科分享 | 赋能物流机器人:CANopen通信如何发挥重要作用?

现代物流领域迅速融入了技术进步&#xff0c;特别是随着自主机器人的兴起&#xff0c;这一趋势越发明显。确保这些机器人在复杂的仓库环境中精确运行的一个关键方面是CANopen通信协议。该协议集成了各种组件&#xff08;电机、传感器、摄像头和先进的电池系统&#xff09;&…

vue视频直接播放rtsp流;vue视频延迟问题解决;webRTC占cpu太大卡死问题解决;解决webRTC播放卡花屏问题:

播放多个视频 <div class"video-box"><div class"video"><iframe style"width:100%;height:100%;" name"ddddd" id"iframes" scrolling"auto" :src"videoLeftUrl"></iframe>&l…

轴承寿命相关细节的研究

数据集PHM2012 介绍一下IEEE PHM2012数据集_phm2012轴承数据集-CSDN博客 标签如何设置的? 剩余寿命预测的标签设置_rul 标签_兔子牙丫丫的博客-CSDN博客 参考自刘硕师兄的毕业答辩PPT 图 4.9 训练数据的切分方法 数据段的重叠切分&#xff0c;不仅可以覆盖更多的标签数据…

任务调度框架-如何实现定时任务+RabbitMQ事务+手动ACK

任务调度框架 Java中如何实现定时任务&#xff1f; 比如&#xff1a; 1.每天早上6点定时执行 2.每月最后一个工作日&#xff0c;考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒&#xff0c;自动提醒 10分钟的超时订单的自动取消&#xff0c;每隔30秒或1分钟查询…

Redis在分布式场景下的应用

分布式缓存 缓存的基本作用是在高并发场景下对应服务的保护缓冲 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; redis由于高强度性能采用内存 但是意味着丢失的风险单结点redis并发能力有限分布式服务中数据过多 依赖内存的redis 明显单机不…

微信小程序自定义组件及投票管理与个人中心界面搭建

14天阅读挑战赛 人生本来就没定义&#xff0c;任何的价值都是自己赋予。 目录 一、自定义tabs组件 1.1 创建自定义组件 1.2 tabs.wxml 编写组件界面 1.3 tabs.wxss 设计样式 1.4 tabs.js 定义组件的属性及事件 二、自定义组件使用 2.1 引用组件 2.2 编写会议界面内容 …