CUDA template kernel 与其他编译器合作编译

本文探讨了在CUDA编程中如何利用C++模板和常量优化Kernel,通过在.cu文件中声明常量函数,使得编译器能够展开循环以提高计算效率。示例代码展示了如何组织源文件,确保模板的正确编译和使用。

简介

在优化Kernel的时候,希望某些变量是常量,例如循环的次数相关的变量。如果次数限制是常量的话,编译器就可以将循环展开。展开的循环,会省掉一些判断,从而节省一些计算时间。

C++的模版中可以使用常量。但是我又不想所有的源代码都由nvcc来编译(其实C++的代码还是调用的host compiler),故此,我写这篇博客来提供一种方法。


代码实例

实例中有三个文件:
main.cpp用host compiler来编译。
cuda_interfaces.cunvcc来编译。

cuda_interfaces.hcuda_interfaces.cu的接口头文件。

// main.cpp
#include <iostream>
#include "cuda_interfaces.h"
int main(int argc, char** argv){
    su::gpu_func<0>();
    su::gpu_func<1>();
    su::gpu_func<2>();
    su::gpu_func<3>();
    su::gpu_func<4>();
    su::gpu_func<5>();
    return EXIT_SUCCESS;
}

// cuda_interfaces.h
#ifndef __CUDA_INTERFACES_H__
#define __CUDA_INTERFACES_H__
namespace su{
    template<int _s> void gpu_func();
}
#endif

// cuda_interfaces.cu
#include <host_defines.h>
#include <device_launch_parameters.h>

#include <iostream>
using namespace std;

namespace su{

    template <int _s>
    __global__ void kernel_func(int *data)
    {
        int x = threadIdx.x + blockIdx.x*blockDim.x;
        if (x < _s){
            data[x] = _s;
        }
        else{
            data[x] = 0;
        }
    }


    template<int _s> void gpu_func()
    {
        int n_threads = 32;
        int *h_data = new int[n_threads];
        int *d_data = NULL;
        cudaMalloc(&d_data, n_threads*sizeof(int));

        kernel_func<_s><<<1, n_threads>>>(d_data);
        cudaMemcpy(h_data, d_data, n_threads*sizeof(int), cudaMemcpyDeviceToHost);

        for (int i = 0; i < n_threads; i++){
            cout << h_data[i] << " ";
        }
        cout << endl;

        // release memory
        delete[] h_data; h_data = NULL;
        cudaFree(d_data); d_data = NULL;
    }

    // note _s only support 0,1,2,3,4,5
    template void gpu_func<0>();
    template void gpu_func<1>();
    template void gpu_func<2>();
    template void gpu_func<3>();
    template void gpu_func<4>();
    template void gpu_func<5>();
}

上述代码执行结果如下:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

关键点

完成在模版中使用常量的关键在于在.cu文件里的声明,告诉nvcc要编译哪几个常量的函数!

Enjoy!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值