Cuda By Example - 11 (Texture Memory 2-D)
跟1D一样,2D的代码也没有运行过。旧的方法看看就好。
声明二维Texture
texture<float, 2> texConstSrc;
texture<float, 2> texIn;
texture<float, 2> texOut;
访问二维Texture
使用2D的Texture的便利性体现在blend_kernel函数里。不再需要通过x,y去计算一维索引。二维texture使用tex2D()去读取数据。
__global__ void blend_kernel( float *dst,bool dstOut ) {// map from threadIdx/BlockIdx to pixel positionint x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int offset = x + y * blockDim.x * gridDim.x;float t, l, c, r, b;if (dstOut) {t = tex2D(texIn,x,y-1);l = tex2D(texIn,x-1,y);c = tex2D(texIn,x,y);r = tex2D(texIn,x+1,y);b = tex2D(texIn,x,y+1);} else {t = tex2D(texOut,x,y-1);l = tex2D(texOut,x-1,y);c = tex2D(texOut,x,y);r = tex2D(texOut,x+1,y);b = tex2D(texOut,x,y+1);}dst[offset] = c + SPEED * (t + b + r + l - 4 * c);
}
然后拷贝热源数据
__global__ void copy_const_kernel( float *iptr ) {// map from threadIdx/BlockIdx to pixel positionint x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int offset = x + y * blockDim.x * gridDim.x;float c = tex2D(texConstSrc,x,y);if (c != 0)iptr[offset] = c;
}
二维Texture绑定
使用2维Texture去绑定一维数组,稍微复杂一些:
cudaChannelFormatDesc desc = cudaCreateChannelDesc<float>();
HANDLE_ERROR( cudaBindTexture2D( NULL, texConstSrc, data.dev_constSrc,desc, DIM, DIM, sizeof(float)*DIM));
HANDLE_ERROR( cudaBindTexture2D( NULL, texIn, data.dev_inSrc,desc, DIM, DIM, sizeof(float)*DIM));
HANDLE_ERROR( cudaBindTexture2D( NULL, texOut, data.dev_outSrc,desc, DIM, DIM, sizeof(float)*DIM));
解除绑定
解除绑定的方式跟1D相同
cudaUnbindTexture(texIn);
cudaUnbindTexture(texOut);
cudaUnbindTexture(texConstSrc);
完整代码
#include "../common/book.h"
#include "../common/cpu_anim.h"#define DIM 1024
#define PI 3.1415926535897932f
#define MAX_TEMP 1.0f
#define MIN_TEMP 0.0001f
#define SPEED 0.25f// these exist on the GPU side
texture<float,2> texConstSrc;
texture<float,2> texIn;
texture<float,2> texOut;__global__ void blend_kernel( float *dst,bool dstOut ) {// map from threadIdx/BlockIdx to pixel positionint x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int offset = x + y * blockDim.x * gridDim.x;float t, l, c, r, b;if (dstOut) {t = tex2D(texIn,x,y-1);l = tex2D(texIn,x-1,y);c = tex2D(texIn,x,y);r = tex2D(texIn,x+1,y);b = tex2D(texIn,x,y+1);} else {t = tex2D(texOut,x,y-1);l = tex2D(texOut,x-1,y);c = tex2D(texOut,x,y);r = tex2D(texOut,x+1,y);b = tex2D(texOut,x,y+1);}dst[offset] = c + SPEED * (t + b + r + l - 4 * c);
}__global__ void copy_const_kernel( float *iptr ) {// map from threadIdx/BlockIdx to pixel positionint x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int offset = x + y * blockDim.x * gridDim.x;float c = tex2D(texConstSrc,x,y);if (c != 0)iptr[offset] = c;
}// globals needed by the update routine
struct DataBlock {unsigned char *output_bitmap;float *dev_inSrc;float *dev_outSrc;float *dev_constSrc;CPUAnimBitmap *bitmap;cudaEvent_t start, stop;float totalTime;float frames;
};void anim_gpu( DataBlock *d, int ticks ) {HANDLE_ERROR( cudaEventRecord( d->start, 0 ) );dim3 blocks(DIM/16,DIM/16);dim3 threads(16,16);CPUAnimBitmap *bitmap = d->bitmap;// since tex is global and bound, we have to use a flag to// select which is in/out per iterationvolatile bool dstOut = true;for (int i=0; i<90; i++) {float *in, *out;if (dstOut) {in = d->dev_inSrc;out = d->dev_outSrc;} else {out = d->dev_inSrc;in = d->dev_outSrc;}copy_const_kernel<<<blocks,threads>>>( in );blend_kernel<<<blocks,threads>>>( out, dstOut );dstOut = !dstOut;}float_to_color<<<blocks,threads>>>( d->output_bitmap,d->dev_inSrc );HANDLE_ERROR( cudaMemcpy( bitmap->get_ptr(),d->output_bitmap,bitmap->image_size(),cudaMemcpyDeviceToHost ) );HANDLE_ERROR( cudaEventRecord( d->stop, 0 ) );HANDLE_ERROR( cudaEventSynchronize( d->stop ) );float elapsedTime;HANDLE_ERROR( cudaEventElapsedTime( &elapsedTime,d->start, d->stop ) );d->totalTime += elapsedTime;++d->frames;printf( "Average Time per frame: %3.1f ms\n",d->totalTime/d->frames );
}// clean up memory allocated on the GPU
void anim_exit( DataBlock *d ) {cudaUnbindTexture( texIn );cudaUnbindTexture( texOut );cudaUnbindTexture( texConstSrc );HANDLE_ERROR( cudaFree( d->dev_inSrc ) );HANDLE_ERROR( cudaFree( d->dev_outSrc ) );HANDLE_ERROR( cudaFree( d->dev_constSrc ) );HANDLE_ERROR( cudaEventDestroy( d->start ) );HANDLE_ERROR( cudaEventDestroy( d->stop ) );
}int main( void ) {DataBlock data;CPUAnimBitmap bitmap( DIM, DIM, &data );data.bitmap = &bitmap;data.totalTime = 0;data.frames = 0;HANDLE_ERROR( cudaEventCreate( &data.start ) );HANDLE_ERROR( cudaEventCreate( &data.stop ) );int imageSize = bitmap.image_size();HANDLE_ERROR( cudaMalloc( (void**)&data.output_bitmap,imageSize ) );// assume float == 4 chars in size (ie rgba)HANDLE_ERROR( cudaMalloc( (void**)&data.dev_inSrc,imageSize ) );HANDLE_ERROR( cudaMalloc( (void**)&data.dev_outSrc,imageSize ) );HANDLE_ERROR( cudaMalloc( (void**)&data.dev_constSrc,imageSize ) );cudaChannelFormatDesc desc = cudaCreateChannelDesc<float>();HANDLE_ERROR( cudaBindTexture2D( NULL, texConstSrc,data.dev_constSrc,desc, DIM, DIM,sizeof(float) * DIM ) );HANDLE_ERROR( cudaBindTexture2D( NULL, texIn,data.dev_inSrc,desc, DIM, DIM,sizeof(float) * DIM ) );HANDLE_ERROR( cudaBindTexture2D( NULL, texOut,data.dev_outSrc,desc, DIM, DIM,sizeof(float) * DIM ) );// initialize the constant datafloat *temp = (float*)malloc( imageSize );for (int i=0; i<DIM*DIM; i++) {temp[i] = 0;int x = i % DIM;int y = i / DIM;if ((x>300) && (x<600) && (y>310) && (y<601))temp[i] = MAX_TEMP;}temp[DIM*100+100] = (MAX_TEMP + MIN_TEMP)/2;temp[DIM*700+100] = MIN_TEMP;temp[DIM*300+300] = MIN_TEMP;temp[DIM*200+700] = MIN_TEMP;for (int y=800; y<900; y++) {for (int x=400; x<500; x++) {temp[x+y*DIM] = MIN_TEMP;}}HANDLE_ERROR( cudaMemcpy( data.dev_constSrc, temp,imageSize,cudaMemcpyHostToDevice ) ); // initialize the input datafor (int y=800; y<DIM; y++) {for (int x=0; x<200; x++) {temp[x+y*DIM] = MAX_TEMP;}}HANDLE_ERROR( cudaMemcpy( data.dev_inSrc, temp,imageSize,cudaMemcpyHostToDevice ) );free( temp );bitmap.anim_and_exit( (void (*)(void*,int))anim_gpu,(void (*)(void*))anim_exit );
}
相关文章:
Cuda By Example - 11 (Texture Memory 2-D)
跟1D一样,2D的代码也没有运行过。旧的方法看看就好。 声明二维Texture texture<float, 2> texConstSrc; texture<float, 2> texIn; texture<float, 2> texOut; 访问二维Texture 使用2D的Texture的便利性体现在blend_kernel函数里。不再需要通…...
Go匿名结构体使用场景
1. 定义 在 Go 语言中,匿名结构体(Anonymous Struct)是一种没有显式命名的结构体类型。你可以直接在代码中定义并使用匿名结构体,而不需要为其定义一个单独的类型名称。匿名结构体通常用于临时数据结构或一次性使用的场景。 匿名…...
Vue 发布十年了!你知道我这十年是怎么过的吗?
2014 年 2 月 3 日,Vue 在 Hacker News 上首次亮相。十年后的今天,Vue 已经成为使用最广泛的前端框架之一,拥有了一个非常丰富的生态系统。本文来梳理一下 Vue.js 十年以来的重要里程碑! 尤雨溪,无疑是 Vue.js 背后的灵…...
Unity 6 来袭
这里写自定义目录标题 1.提升渲染性能1.1 降低CPU开销 Lower CPU overhead1.2.减少内存带宽1.3.高档低分辨率帧2.多人游戏创作3.扩大多平台覆盖范围3.1.增进Android平台开发4.使用Runtime AI解锁各种可能性4.1.Unity Muse4.2.Unity Sentis5.实现更具吸引力的视觉效果5.1.自适应…...
SpringMVC课时1
一:SpringMVC Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,负责表述层(控制层)实现简化。 由于 Spring MVC 本身就是 Spring 框架的一部分,和 Spring 框架是无缝集成。 二:SSM的主要作用 三:SpringMVC的原理架构图 …...
【小白学机器学习30】样本统计的核心参数:均值/期望,方差,标准差,标准值。
目录 1 为什么我们要搞出来这么多指标/参数? 1.1 描述统计学为啥要搞出来这么多复杂的参数?什么平均值等 1.2 所以,需要用少数几个关键数据代表1群数据 1.2.1 平均值 1.2.2 平均值的问题:方差 2 代表性的数据1:…...
flink1.17.2安装和使用
版本:flink1.17.2 单机模式 配置 # 为了在别处连接flink-web rest.bind-address: 0.0.0.0命令 # 启动集群 bin/start-cluster.sh # 关闭集群 bin/stop-cluster.sh使用 使用浏览器连接 ip:8081 使用flink-web...
C向C++入门-- C语言填坑
1.c参考文档 我们在学习c中需要查找参照信息到是从这些文档中得到。 https://legacy.cplusplus.com/reference/ 标准只更新到C11,但是以头⽂件形式呈现,内容⽐较易看好懂。 https://zh.cppreference.com/w/cpp https://en.cppreference.com/w/ 后两…...
扫雷游戏(C语言详解)
扫雷游戏(C语言详解) 放在最前面的1、前言(扫雷游戏的简介)2、扫雷游戏的规则(简易版)3、代码实现(3.1)提醒一下:( i ) 提醒1:( ii ) 提醒2: &…...
信刻全自动光盘摆渡系统
随着各种数据传输、储存技术、信息技术的快速发展,保护信息安全是重中之重。各安全领域行业对跨网数据交互需求日益迫切。针对于业务需要与保密规范相关要求,涉及重要秘密信息,需做到安全的物理隔离,并且保证跨网数据高效安全传输…...
计算机网络的数据链路层
计算机网络的数据链路层 数据链路层是OSI参考模型中的第二层,它位于物理层之上,网络层之下。数据链路层的主要功能是在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层。…...
从0开始搭建一个生产级SpringBoot2.0.X项目(三)SpringBoot接口统一返回和全局异常处理
前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 SpringBoot接口统一返回和全局异常处理,使用ControllerAdvice ExceptionHandler 的组合来实现。 一、pom文件新增依赖 <dependency><groupId>com.alibaba</groupId><ar…...
Mybatis-plus-扩展功能
Mybatis-plus-扩展功能 一:代码生成器 AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。 功能的演示:…...
【AI辅助】AWS Toolkit+AmazonQ
#偶然看到网上某up主用的这个AI工具,感觉还挺实用的,推荐大家~我们不可阻挡AI的攻势,但是成为利用它的人,也是反侵占的方式呢# AWS toolkit Amazon Q 安装 VScode--Extensions--搜索工具--安装 安装后,工具栏会多出对…...
云手机简述(概况,使用场景,自己部署云手机)
背景 最近经常会看到云手机的相关广告,手痒难耐,了解一下。 我的主要需求: Android 已 root,能够做一些自动化等高级功能。能够通过 远程adb 控制手机。能够尽量的少花钱,最好是能够提供动态创建删除手机的方式&…...
Java已死,大模型才是未来?
作者:不惑_ 引言 在数字技术的浪潮中,编程语言始终扮演着至关重要的角色。Java,自1995年诞生以来,便以其跨平台的特性和丰富的生态系统,成为了全球范围内开发者们最为青睐的编程语言之一 然而,随着技术的…...
NCCL安装(Ubuntu等)
目录 一、NCCL的定义二、安装NCCL的原因1、加速多GPU通信2、支持流行的深度学习框架3、提高计算效率4、易于使用和集成5、可扩展性 三、NCCL安装方法1、下载安装包2、更新APT数据库3、使用APT安装libnccl2包,另外,如果需要使用NCCL编译应用程序ÿ…...
加载视频显示 - python 实现
#-*-coding:utf-8-*- # date:2021-03-21 # Author: DataBall - Xian # Function: 加载视频并显示import cv2 if __name__ "__main__":#加载视频cap cv2.VideoCapture(./video/1.mp4)while True:ret, img cap.read()# 获取相机图像if ret True:# 如果 ret 返回值为…...
数据结构模拟题[五]
数据结构试卷(五) 一、选择题 (20 分) 1.数据的最小单位是( )。 (A) 数据项 (B) 数据类型 (C) 数据元素 (D) 数据变量 2.设一组初始记录关键字序列为 (50 ,40, 95,20…...
IDEA切换窗口快捷键失效
问题描述: 在idea中,如果切换窗口的快捷键(Alt Tab)失效了,可以通过清除缓存的方式修复...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
