模板是C++的一个重要特征,它可以让我们简化代码,同时使代码更整洁。CUDA中也支持模板,这给我们编写cuda程序带来了方便。不过cuda4.0之前和之后使用模板的方法不一样,这给我们带来了少许困难。在cuda4.0之前,模板的使用和C++中无区别,使用非常方便,在此不做过多介绍。不过在cuda4.0之后,由于编译器的升级,导致之前的模板使用方法不再有效,我们需要重新设计代码。

如果按照之前的方式编写代码,如下面简单示例:

template <type T>
__global__ void foo(T *odata, T* idata)
{
extern __shared__ T sdata[];
// ... do stuff with odata, idata, and sdata
}
foo<int><<<blocks, threads, mem>>>(d_odata, d_idata);
foo<float><<<blocks, threads, mem>>>(d_odata, d_idata);
编译之后会遇到下述错误:“declaration is incompatible with previous "sdata" (declared at line 3)extern __declspec(__shared__) T sdata[];”。原因就是在编译的时候,cuda会为上述两次调用生成相同的代码,因而会出现变量重复定义的问题。

解决方法如下:将模板类实例化。首先新建一个头文件,SharedMem.h,内容如下:

#include <cutil_inline.h>
template <class T>
class SharedMem
{
public:
T* getPointer() { return NULL; };
}; // specialization for int
template <>
class SharedMem <int>
{
public:
__device__ int* getPointer() { extern __shared__ int s_int[]; return s_int; }
}; // specialization for float
template <>
class SharedMem <float>
{
public:
__device__ float* getPointer() { extern __shared__ float s_float[]; return s_float; }
};

上述代码实际上就是将定义共享内存的代码单独拿出来,然后放在类中实现。上述代码需要注意以下几个方面:

1.       因为在定义共享内存时用到关键字__shared__,所以我们要将函数定义成cuda函数。在函数前面需要加相应关键字,但不能是__global__,因为它要求返回void类型,所以只能是__device__;

2.       包含cuda程序相应的头文件,否则编译不通过;

完成上述头文件的编写,在具体调用过程中代码如下:

template<class T>
__global__ void foo( T* g_idata, T* g_odata)
{
// shared memory the size is determined by the host application SharedMem<T> shared;
T* sdata = shared.getPointer(); // .. the rest of the code remains unchanged!
}

这样我们就可以在cuda中正常使用模板了。

参考网页:

1. cuda中应用模板函数

2. simpleTemplates

cuda中模板的使用的更多相关文章

  1. CUDA中关于C++特性的限制

    CUDA中关于C++特性的限制 CUDA官方文档中对C++语言的支持和限制,懒得每次看英文文档,自己尝试翻译一下(没有放lambda表达式的相关内容,太过于复杂,我选择不用).官方文档https:// ...

  2. tornado学习笔记11 Web应用中模板(Template)使用应用实践

    上一篇中(Web应用中模板的工作流程分析),已经分析了模板的渲染流程,以及相关参数获取及设置原理.这篇主要讲述模板在实际应用案例. 11.1 需求 根据用户输入的两次密码,判断两次密码是否一致,并将判 ...

  3. wpf 获取datagrid中模板中控件

    //获取name为datagrid中第三列第一行模板的控件 FrameworkElement item = dataGrid.Columns[].GetCellContent(dataGrid.Ite ...

  4. CUDA中并行规约(Parallel Reduction)的优化

    转自: http://hackecho.com/2013/04/cuda-parallel-reduction/ Parallel Reduction是NVIDIA-CUDA自带的例子,也几乎是所有C ...

  5. cuda中时间用法

    转载:http://blog.csdn.net/jdhanhua/article/details/4843653 在CUDA中统计运算时间,大致有三种方法: <1>使用cutil.h中的函 ...

  6. OpenCV二维Mat数组(二级指针)在CUDA中的使用

    CUDA用于并行计算非常方便,但是GPU与CPU之间的交互,比如传递参数等相对麻烦一些.在写CUDA核函数的时候形参往往会有很多个,动辄达到10-20个,如果能够在CPU中提前把数据组织好,比如使用二 ...

  7. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  8. 多个so中模板单例的多次实例化

    在Android打包项目时,发现登录功能不能使用了,logcat中也没发现什么问题,最后一行一行log定位到了问题.原来是一个so文件中的构造函数被初始化二次!   这个单例是通过继承模板来实现的(暂 ...

  9. Django项目中模板标签及模板的继承与引用【网站中快速布置广告】

    Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...

随机推荐

  1. PHP While 循环

    PHP 循环 - While 循环 循环执行代码块指定的次数,或者当指定的条件为真时循环执行代码块. PHP 循环 在您编写代码时,您经常需要让相同的代码块一次又一次地重复运行.我们可以在代码中使用循 ...

  2. 事务的特性(ACID)

    一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 准备工作:为了说明事务的ACID原理,我们使用银行账户及资金管理的案例进行分析. // 创建 ...

  3. Spring常用配置

    ----------------------------------------------------------------------------------------------[版权申明: ...

  4. RTMPdump(libRTMP)源代码分析 4: 连接第一步——握手(Hand Shake)

    ===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...

  5. 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现

    本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...

  6. GDALWarp设置GDALWarpOptions::dfWarpMemoryLimit过大时处理失败

    使用GDALWarp写了一个裁切图像的算法,在小内存的电脑没事,大内存的电脑就处理失败(32位也没问题),查看GDAL的日志发现下面的错误信息: Fri Apr 08 17:39:02 2016: G ...

  7. ROS(indigo) 用于机器人控制的图形化编程工具--code_it robot_blockly

    0 简介: 编程语言有汇编,高级语言,解释语言等,现在图形化编程也越来越流行.图形化编程简单易学.8年前,微软推出了VPL用于机器人程序设计,如Python和JavaScript都可以用图形化框图实现 ...

  8. Python 3 智能发音

    真是十分神奇.. import win32com.client import time s = win32com.client.Dispatch("SAPI.SpVoice") s ...

  9. Java异常处理-----非运行时异常(受检异常)

    非运行时异常(受检异常) 如果出现了非运行时异常必须进行处理throw或者try{}catch(){}处理,否则编译器报错. 1:IOException 使用要导入包import java.io.IO ...

  10. 微信开发获取地理位置实例(java,非常详细,附工程源码)

    在本篇博客之前,博主已经写了4篇关于微信相关文章,其中三篇是本文基础: 1.微信开发之入门教程,该文章详细讲解了企业号体验号免费申请与一些必要的配置,以及如何调用微信接口. 2.微信开发之通过代理调试 ...