0_Simple__simpleSeparateCompilation
▶ 简单的将纯 C/C++ 函数放到另一个文件中,利用头文件引用到主体 .cu 中来,编译时共同编译。
▶ 源代码,把 C++ 的部分去掉了
// simpleDeviceLibrary.cuh
#ifndef SIMPLE_DEVICE_LIBRARY_CUH
#define SIMPLE_DEVICE_LIBRARY_CUH extern "C" __device__ float multiplyByTwo(float number); extern "C" __device__ float divideByTwo(float number); #endif
// simpleDeviceLibrary.cu
#include <cuda_runtime.h> extern "C" __device__ float multiplyByTwo(float number)
{
return number * 2.0f;
} extern "C" __device__ float divideByTwo(float number)
{
return number * 0.5f;
}
// simpleSeparateCompilation.cu
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include "simpleDeviceLibrary.cuh" #define EPS 1e-5 typedef float(*deviceFunc)(float);
__device__ deviceFunc dMultiplyByTwoPtr = multiplyByTwo; // 本地声明,直接在代码中调用 multiplyByTwo / divideByTwo 会导致运行时错误
__device__ deviceFunc dDivideByTwoPtr = divideByTwo; __global__ void transformVector(float *v, deviceFunc f, unsigned int size)
{
unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x;
if (tid < size)
v[tid] = (*f)(v[tid]);
} int test()
{
cudaSetDevice();
const unsigned int size = ;
float hVector[size], hResultVector[size], *dVector;
for (unsigned int i = ; i < size; ++i)
{
hVector[i] = rand() / (float)RAND_MAX;
hResultVector[i] = 0.0f;
}
cudaMalloc((void **)&dVector, size * sizeof(float));
cudaMemcpy(dVector, hVector, sizeof(float) * size, cudaMemcpyHostToDevice); deviceFunc hFunctionPtr; // 作为调用参数的函数指针
cudaMemcpyFromSymbol(&hFunctionPtr, dMultiplyByTwoPtr, sizeof(deviceFunc)); // 给 hFunctionPtr 一个地址,方便调用
transformVector << <, >>>(dVector, hFunctionPtr, size);
cudaMemcpyFromSymbol(&hFunctionPtr, dDivideByTwoPtr, sizeof(deviceFunc));
transformVector << <, >> > (dVector, hFunctionPtr, size); cudaMemcpy(hResultVector, dVector, sizeof(float) * size, cudaMemcpyDeviceToHost);
cudaDeviceSynchronize();
if (dVector)
cudaFree(dVector);
for (int i = ; i < size; ++i)
{
if (fabs(hVector[i] - hResultVector[i]) > EPS)
{
printf("\nError at i == %d, hVector[i] == %f, hResultVector[i] == %f", i, hVector[i], hResultVector[i]);
return ;
}
}
return ;
} int main()
{
printf("\n\tStart.\n");
printf("\n\tFinish: %s\n", test() ? "Pass" : "Fail");
getchar();
return ;
}
● 输出结果:
Start.
Finish: Pass
▶ 涨姿势
// cuda_runtime_api.h
#define __dv(v) \
= v extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol(void *dst, const void *symbol, size_t count, size_t offset __dv(), enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost));
// 从指定符号 symbol 处偏移 offset 字节处,拷贝 count 字节到 dst,默认模式为设备拷到主机
0_Simple__simpleSeparateCompilation的更多相关文章
随机推荐
- 20155229 2016-2017-2 《Java程序设计》第五周学习总结
20155229 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第八章: Java中所有错误都会被打包为对象. 设计错误对象都继承自java.lang.Th ...
- Slack 开发入门之 Incoming Webhooks:往 Slack 的 Channel 中发消息
一个工程师团队使用 Slack 进行团队协作比 QQ / 微信流的效率高多啦.除了基本的 IM 之外,它的扩展性也是非常重要的一点. 本文介绍 Slack 的开发入门:Incoming Webhook ...
- LG1801 【黑匣子_NOI导刊2010提高(06)】
看到各路dalao用平衡树的做法,表示本人不才,并不会. 然而我会优先队列_huaji_,并且发现用堆解题的dalao们并没有基于在线的做法 于是我的showtime到了 评测结果:https://w ...
- JVM 加载class文件的原理
PS:类的装载过程是ClassLoader,只有把类 加载 到 JVM后才能运行: PS:两种加载类的方式: 显示:new 隐式:class.forname() PS:动态的执行,用到谁,加载谁:
- java开发中的常见类和对象-建议阅读时间3分钟
1.Dao 数据访问对象 此对象用于访问数据库.实现类一般用于用于操作数据库! 一般操作修改,添加,删除数据库操作的步骤很相似,就写了一个公共类DAO类 ,修改,添加,删除数据库操作时 直接调用公共类 ...
- UltraEdit常用设置及快捷键
= 关闭自动加载上次文件的方法,操作方法如下:首先,要打开UltraEdit,然后点击经[高级]-[配置],找到[文件处理]-[加载],把[重新载入先前在启动时打开的文件]勾去掉,并确定就可以了. 附 ...
- 教你如何阅读Oracle数据库官方文档
< Ask Oracle官方原创 > Oracle 官方文档 数量庞大,而且往往没有侧重点,让oracle新手看起来很费力.但是,仍有很多Oracle使用者认为任何oracle学习资料都比 ...
- mybatis 生成 映射文件生成工具 mybatisGenerator 使用
第一:新建 generatorConfig.xml 文件 ,写入下面的 内容 <?xml version="1.0" encoding="UTF-8"?& ...
- Apache Shiro在web开发安全框架中的应用
前阶段就hadoop的分享了一些内容,希望对新手入门的朋友有点帮助吧!对于hadoop新手入门的,还是比较推荐大快搜索的DKHadoop发行版,三节点标准版还是值得拥有的(三节点的标准版是可以免费下载 ...
- ubuntu卸载vsftpd出错
卸载vsftpd出错 $ sudo apt remove vsftpd Reading package lists... Done Building dependency tree Reading s ...