模板是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. J-Link固件烧录以及使用J-Flash向arm硬件板下载固件程序

    这篇文章的最初版本是在15年写的https://blog.csdn.net/u010592722/article/details/45575663,后来又遇到了一些新问题,故更新在了这里. 一.始于安 ...

  2. Ubuntu 16.04 + ROS Kinetic 机器人操作系统学习镜像分享与使用安装说明

    Ubuntu 16.04 + ROS Kinetic 镜像分享与使用安装说明 内容概要:1 网盘文件介绍  2 镜像制作  3 系统使用与安装 ---- 祝ROS爱好者和开发者新年快乐:-) ---- ...

  3. 自定义下拉刷新上拉加载View

    MainActivity.java package com.heima52.pullrefresh; import java.util.ArrayList; import com.heima52.pu ...

  4. Android的AIDL机制

    Android 接口定义语言 (AIDL) AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似. 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的 ...

  5. Redis工作系列之一 与 Memcached对比理解

         近期公司项目在使用Redis,这几年Redis很火,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memcached的比较更是比比皆是.然而,Redis真的 ...

  6. 操作系统服务:OS模块

    http://blog.csdn.net/pipisorry/article/details/52454486 一般的操作系统服务之OS模块Generic Operating System Servi ...

  7. Spark技术内幕:Executor分配详解

    当用户应用new SparkContext后,集群就会为在Worker上分配executor,那么这个过程是什么呢?本文以Standalone的Cluster为例,详细的阐述这个过程.序列图如下: 1 ...

  8. Qualcomm平台camera调试移植入门

    1  camera基本代码架构 高通平台对于camera的代码组织,大体上还是遵循Android的框架:即上层应用和HAL层交互,高通平台在HAL层里面实现自己的一套管理策略:在kernel中实现se ...

  9. (七十四)iOS8之前使socket可以后台运行的方法

    对于使用socket通信的应用程序,常常希望App位于后台时仍然可以进行网络通信,这在iOS8和以后的版本是被默认允许的,socket可以直接在后台运行,而对于iOS8之前的版本就不行,需要进行两步设 ...

  10. jquery 只读

    大家都理解这是什么,正常的写法如下: if (status == true) { $("#minDelistStr").val(totalAmount);// 去掉首部的" ...