CUDA中的常量内存__constant__
GPU包含数百个数学计算单元,具有强大的处理运算能力,可以强大到计算速率高于输入数据的速率,即充分利用带宽,满负荷向GPU传输数据还不够它计算的。CUDA C除全局内存和共享内存外,还支持常量内存,常量内存用于保存在核函数执行期间不会发生变化的数据,使用常量内存在一些情况下,能有效减少内存带宽,降低GPU运算单元的空闲等待。
使用常量内存提升性能
使用常量内存可以提升运算性能的原因如下:
- 对常量内存的单次读操作可以广播到其他的“邻近(nearby)”线程,这将节约15次读取操作;
 - 高速缓存。常量内存的数据将缓存起来,因此对于相同地址的连续操作将不会产生额外的内存通信量;
 
常量内存的声明
常量内存使用示例
#include "cuda_runtime.h"
#include <highgui/highgui.hpp>
#include <time.h>
using namespace cv;
#define INF 2e10f
#define rnd(x) (x*rand()/RAND_MAX)
#define SPHERES 100 //球体数量
#define DIM 1024    //图像尺寸
struct Sphere
{
	float r, g, b;
	float radius;
	float x, y, z;
	__device__ float hit(float ox, float oy, float *n)
	{
		float dx = ox - x;
		float dy = oy - y;
		if (dx*dx + dy*dy < radius*radius)
		{
			float dz = sqrt(radius*radius - dx*dx - dy*dy);
			*n = dz / sqrt(radius*radius);
			return dz + z;
		}
		return -INF;
	}
};
// Sphere *s;
__constant__ Sphere s[SPHERES];
/************************************************************************/
//__global__ void rayTracing(unsigned char* ptr, Sphere* s)
__global__ void rayTracing(unsigned char* ptr)
{
	int x = threadIdx.x + blockIdx.x * blockDim.x;
	int y = threadIdx.y + blockIdx.y * blockDim.y;
	int offset = x + y  * blockDim.x * gridDim.x;
	float ox = (x - DIM / 2);
	float oy = (y - DIM / 2);
	float r = 0, g = 0, b = 0;
	float maxz = -INF;
	for (int i = 0; i < SPHERES; i++)
	{
		float n;
		float t = s[i].hit(ox, oy, &n);
		if (t > maxz)
		{
			float fscale = n;
			r = s[i].r * fscale;
			g = s[i].g * fscale;
			b = s[i].b * fscale;
			maxz = t;
		}
	}
	ptr[offset * 3 + 2] = (int)(r * 255);
	ptr[offset * 3 + 1] = (int)(g * 255);
	ptr[offset * 3 + 0] = (int)(b * 255);
}
/************************************************************************/
int main(int argc, char* argv[])
{
	cudaEvent_t start, stop;
	cudaEventCreate(&start);
	cudaEventCreate(&stop);
	cudaEventRecord(start, 0);
	Mat bitmap = Mat(Size(DIM, DIM), CV_8UC3, Scalar::all(0));
	unsigned char *devBitmap;
	(cudaMalloc((void**)&devBitmap, 3 * bitmap.rows*bitmap.cols));
	//  cudaMalloc((void**)&s, sizeof(Sphere)*SPHERES);  
	Sphere *temps = (Sphere*)malloc(sizeof(Sphere)*SPHERES);
	srand(time(0));  //随机数种子
	for (int i = 0; i < SPHERES; i++)
	{
		temps[i].r = rnd(1.0f);
		temps[i].g = rnd(1.0f);
		temps[i].b = rnd(1.0f);
		temps[i].x = rnd(1000.0f) - 500;
		temps[i].y = rnd(1000.0f) - 500;
		temps[i].z = rnd(1000.0f) - 500;
		temps[i].radius = rnd(100.0f) + 20;
	}
	//  cudaMemcpy(s, temps, sizeof(Sphere)*SPHERES, cudaMemcpyHostToDevice);
	cudaMemcpyToSymbol(s, temps, sizeof(Sphere)*SPHERES);
	free(temps);
	dim3 grids(DIM / 16, DIM / 16);
	dim3 threads(16, 16);
	//  rayTracing<<<grids, threads>>>(devBitmap, s);
	rayTracing << <grids, threads >> > (devBitmap);
	cudaMemcpy(bitmap.data, devBitmap, 3 * bitmap.rows*bitmap.cols, cudaMemcpyDeviceToHost);
	cudaEventRecord(stop, 0);
	cudaEventSynchronize(stop);
	float elapsedTime;
	cudaEventElapsedTime(&elapsedTime, start, stop);
	printf("Processing time: %3.1f ms\n", elapsedTime);
	imshow("CUDA常量内存使用示例", bitmap);
	waitKey();
	cudaFree(devBitmap);
	//  cudaFree(s);
	return 0;
}
CUDA中的常量内存__constant__的更多相关文章
- GPU CUDA常量内存使用
		
#include <cuda.h> #include <stdio.h> int getMulprocessorCount(){ cudaDeviceProp prop; cu ...
 - 《GPU高性能编程CUDA实战》第六章 常量内存
		
▶ 本章介绍了常量内存的使用,并给光线追踪的一个例子.介绍了结构cudaEvent_t及其在计时方面的使用. ● 章节代码,大意是有SPHERES个球分布在原点附近,其球心坐标在每个坐标轴方向上分量绝 ...
 - CUDA: 常量内存与事件
		
常量内存: 常量内存用于保存在核函数执行期间不会发生变化的数据,在变量面前添加 __constant__ 修饰符: __constant__ Sphere s[SPHERES]; cudaMe ...
 - CUDA中多维数组以及多维纹理内存的使用
		
纹理存储器(texture memory)是一种只读存储器,由GPU用于纹理渲染的图形专用单元发展而来,因此也提供了一些特殊功能.纹理存储器中的数据位于显存,但可以通过纹理缓存加速读取.在纹理存储器中 ...
 - 【CUDA 基础】5.0 共享内存和常量内存
		
title: [CUDA 基础]5.0 共享内存和常量内存 categories: - CUDA - Freshman tags: - 共享内存 - 常量内存 toc: true date: 2018 ...
 - Eclipse中的快捷键快速生成常用代码(例如无参、带参构造,set、get方法),以及Java中重要的内存分析(栈、堆、方法区、常量池)
		
(一)Eclipse中的快捷键: ctrl+shift+f自动整理选择的java代码 alt+/ 生成无参构造器或者提升信息 alt+shift+s+o 生成带参构造 ctrl+shift+o快速导 ...
 - cuda学习3-共享内存和同步
		
为什么要使用共享内存呢,因为共享内存的访问速度快.这是首先要明确的,下面详细研究. cuda程序中的内存使用分为主机内存(host memory) 和 设备内存(device memory),我们在这 ...
 - GPU编程自学7 —— 常量内存与事件
		
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...
 - CUDA中关于C++特性的限制
		
CUDA中关于C++特性的限制 CUDA官方文档中对C++语言的支持和限制,懒得每次看英文文档,自己尝试翻译一下(没有放lambda表达式的相关内容,太过于复杂,我选择不用).官方文档https:// ...
 
随机推荐
- 连接mongodb,kafka异步处理代码
			
1. mongodb异步处理 依赖: <dependencies> <dependency> <groupId>org.mongodb</groupId> ...
 - (转)yum & wget代理设置
			
转自 http://www.cnblogs.com/windows/archive/2012/12/14/2817533.html yum 配置代理服务器访问要设置所有 yum 操作都使用代理服 ...
 - (转)curl 命令使用
			
原文地址:http://blog.sina.com.cn/s/blog_4b9eab320100slyw.html 可以看作命令行浏览器 1.开启gzip请求curl -I http://www.si ...
 - Xvisor ARM32 启动分析
			
Linux内核历史悠久,特性丰富,但是代码量庞大,各个子系统交叉繁琐.对于想要将操作系统内核各个特性研究一遍的人,有时候也只好"望Linux兴叹".Xvisor是一个较新的Type ...
 - [Angular] Learn Angular Multi-Slot Content Projection
			
Now for au-modal component, we pass in tow component though contenct projection: <au-modal class= ...
 - HDU 1213 How Many Tables 并查集 水~
			
http://acm.hdu.edu.cn/showproblem.php?pid=1213 果然是需要我陪跑T T,禽兽工作人员还不让,哼,但还是陪跑了~ 啊,还有呀,明天校运会终于不用去了~耶耶耶 ...
 - [Javascript Natural] Break up language strings into parts using Natural
			
A part of Natural Language Processing (NLP) is processing text by “tokenizing” language strings. Thi ...
 - 特殊类型数据:IP地址字段(IPv4)
			
人们经常使用varchar(15)来存储ip地址,然而,它们实际上是32位无符号整数,不是字符串. MySQL提供INET_ATON()和INET_NTOA()函数将ip地址在整数和四段表示形式之间进 ...
 - Android Wear之android穿戴式设备应用开发平台
			
Android Wear于2014年03月19日公布,并有Moto 360和LG watch两款产品. 眼下源代码还没有开放.可是开发人员能够下载它的Image及相应的开发SDK,这样开发人员通过模拟 ...
 - 自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法
			
前言:这几天做客户回访,感触很大,用户只要是留反馈信息,总是一种恨铁不成钢的心态,想用你的app,却是因为你的技术问题,让他们不得不放弃,而你一个回访电话却让他们尽释前嫌,当最后把手机号留给他们以便随 ...