▶ 简单的将纯 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的更多相关文章

随机推荐

  1. HDU 4640 状态压缩DP 未写完

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640 解题思路: 首先用一个简单的2^n*n的dp可以求出一个人访问一个给定状态的最小花费,因为这i个 ...

  2. SharePoint 列表多表联合查询

    在SharePoint平台二次开发中,我们有时需要涉及多表关联查询展示多列表中的不同字段信息:SharePoint和Sql数据表一样,也支持多表联合查询,但是不像Sql语句那样简单,有一定的局限性,需 ...

  3. test20180921 量子纠缠

    题意 问题描述 万能的红太阳J 君正在研究量子信息的纠缠. 具体来说,J 君有一个初始为空的信息集.她会进行m 次操作,有时,她会向信息集内加入一个长度不超过L 的的数字串(一个数字串为一个仅由0 到 ...

  4. streamsets 3.5 的一些新功能

    streamsets 3.5 有了一些新的特性以及增强,总之是越来越方便了,详细的可以 查看官方说明,以下简单例举一些比较有意义的. origins 新的pulsar 消费origin jdbc 多表 ...

  5. dup and dup2的剖析

    转:http://www.cnblogs.com/sdphome/archive/2011/04/30/2033381.html dup和dup2都可用来复制一个现存的文件描写叙述符,使两个文件描写叙 ...

  6. java 创建子类

    当程序创建子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为他从父类继承得到的所有实例变量分配内存,即使子类中定义了与父类中同名的实例变量. 如: class Parent { privat ...

  7. PHP接口开发加密技术实例原理与例子

    下面例子简单讲解PHP接口开发加密技术:如app要请求用户列表,api是“index.php?module=user&action=list”app生成token = md5sum (‘use ...

  8. MySQL数据库服务器整体规划(go)

    我们在搭建MySQL数据库服务器的开始阶段就合理的规划,可以避免以后的很多问题的产生,大大节省我们的时间和精力,在一定幅度上降低成本.当然,这会涉及很多方面.比如机器的选型.业务评估和系统规划等. 所 ...

  9. box-shadow 边框样式

    如下 box-shadow: 0 1px 3px 0 rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.1 ...

  10. 2018-2019 网络对抗技术 20165226 Exp4:恶意代码分析

    2018-2019 网络对抗技术 20165226 Exp4:恶意代码分析 目录 一.实验内容说明及基础问题回答 二.实验过程 Task1 系统运行监控 结合windows计划任务与netstat命令 ...