▶ 简单的将纯 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. 20155224 2016-2017-2 《Java程序设计》第5周学习总结

    20155224 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 Java中的错误都会被打包为对象,可以尝试(try)捕捉(catch)代表错误的对象 ...

  2. CTF之MD5

    MD5是一种常见的加密方式,但准确来说,它只是一种编码方式,它将任意有限长度的字符串通过哈希函数转换为特定长度的字符串. MD5编码具有单向性,即由明文变密文简单,由密文变明文困难. 破解时只能通过暴 ...

  3. ACM中的取模

    取模本身的性质:(之前有一篇博客写过)三则运算(+,-,*)过程中的取模与最后的取模一样(前提是最后不超long long(或int) 范围,所以为防止超范围,直接对三则运算中的过程取模) 然后就是A ...

  4. 《DSP using MATLAB》Problem 4.2

    用matlab不会证,惭愧.

  5. poj1797 最短路

    虽然不是求最短路,但是仍然是最短路题目,题意是要求1到N点的一条路径,由于每一段路都是双向的并且有承受能力,求一条路最小承受能力最大,其实就是之前POJ2253的翻版,一个求最大值最小,一个求最小值最 ...

  6. 浏览器通过http协议通过nginx访问ftp服务器上的文件

    1.修改nginx配置文件 2.修改nginx默认目录为ftp默认目录 3.修改成自定义路径后,并修改此目录第一行,修改为root或是nginx用户 4.重新加载 cd /usr/local/ngin ...

  7. jquery.ellipsis根据宽度(不是字数)进行内容截断,支持多行内容

    jquery.ellipsis 自动计算内容宽度(不是字数)截断,并加上省略号,内容不受中英文或符号限制. 如果根据字数来计算的话,因为不同字符的宽度并不相同,比如l和W,特别是中英文,最终内容宽度会 ...

  8. RAC5——11gR2以后GI进程的变化

    参考文档: 11gR2 Clusterware and Grid Home - What You Need to Know (Doc ID 1053147.1)诊断 Grid Infrastructu ...

  9. vue 文件中的注释

    在每个代码块内,注释的时候,需要使用各自语言的注释语法去注释(HTML.CSS.JavaScript.Jade 等).在文件最顶部注释的时候用HTML的注释语法:<!- 在这里写注释的内容 -- ...

  10. 如何调试触发器-MSSQL (转帖)

    调试触发器 //------------------------------------- 作者:四海为圈(原创) //------------------------------------- 1. ...