cuda数组找出最值

cuda数组找出最值

既是记录自己书写的代码 也是方便以后用到代码的时候可以直接复制粘贴,有什么问题或者好的建议 可以私信我 我会耐心回复

本文出现的一些常用宏定义

#define CUDA_ID            \
    uint3 tid = threadIdx; \
    uint3 bid = blockIdx;  \
    uint3 bdim = blockDim; \
    uint3 gdim = gridDim

#define MYID \
    CUDA_ID; \
    const int id = bid.x * bdim.x + tid.x

#define MYSRD(T) extern SRD int srd[];  T *tsrd = (T *)srd

#define CDTSYNC __syncthreads()

#define IFBIGEQ(eq, big) if(eq < big)  eq = big
#define IFSMLEQ(eq, small) if(eq > small) eq = small

#define _IN_OUT_
#define _IN_
#define _OUT_

#define _ARR_
#define _VAL_
#define _IN_VAL_
#define _OUT_VAL_
#define _IN_ARR_
#define _OUT_ARR_
#define _IO_ARR_
#define _IO_VAL_

工具方法

默认线程块和线程格的y和z都是1,自动计算线程格和线程块的规模

void calculateScalar_grid_block(const int size, dim3& grid, dim3& block, int device_num)
{
    cudaSetDevice(device_num);
    cudaDeviceProp property;
    cudaGetDeviceProperties(&property, device_num);

    grid.x = grid.y = grid.z = block.x = block.y = block.z = 1;

    int maxThreadsPerBlock = property.maxThreadsPerBlock;
    if (size <= maxThreadsPerBlock)
    {
        block.x = size;
    }
    else
    {
        block.x = maxThreadsPerBlock;
        grid.x = std::ceil(size / flt(maxThreadsPerBlock));
    }
}

调用的cuda的内核方法

方法命名还有待改善

template <typename T3>
GLB void findARR3maxmin(_IN_ _ARR_ const T3 *data, _IN_ _VAL_ cintp datasize, _OUT_ _ARR_ T3 *dest, bool is_max = true)
{
    MYID;

    if (id < *datasize)
    {
        MYSRD(T3);

        tsrd[tid.x] = data[id];
        CDTSYNC;

        for (int a = 1; a < bdim.x; a *= 2)
        {
            if (tid.x % (a * 2) == 0)
            {
                if (tid.x + a < bdim.x)
                {
                    if (is_max)
                    {
                        IFBIGEQ(tsrd[tid.x].x, tsrd[tid.x + a].x);
                        IFBIGEQ(tsrd[tid.x].y, tsrd[tid.x + a].y);
                        IFBIGEQ(tsrd[tid.x].z, tsrd[tid.x + a].z);
                    }
                    else
                    {
                        IFSMLEQ(tsrd[tid.x].x, tsrd[tid.x + a].x);
                        IFSMLEQ(tsrd[tid.x].y, tsrd[tid.x + a].y);
                        IFSMLEQ(tsrd[tid.x].z, tsrd[tid.x + a].z);
                    }
                }
                CDTSYNC;
            }
        }

        if (id == 0)
            dest[bid.x] = tsrd[0];
    }
}

主要方法

找max和找min同理, 只需要把内部的大小写逻辑修改一下就可以了

代码还不算完善 可以再增加一个变量 来确定寻找的是最大值还是最小值

template <typename T3>
void getArray_maxmin(_IN_ _ARR_ const T3 *data, _IN_ _VAL_ cintr size, _OUT_ _ARR_ T3 *dest, bool is_max = true)
{
    CDACCPY(T3, d_arr, size, data);

    CDCCPYV(int, d_arr_size, size);

    dim3 grid, block;
    calculateScalar_grid_block(size, grid, block);

    int srdsize = block.x * sizeof(T3);

    CDANV(T3, d_max, grid.x);

    while (true)
    {
        findARR3maxmin<<<grid, block, srdsize>>>(d_arr, d_arr_size, d_max, is_max);
        BASE_SYNC;

        if (grid.x == 1)
        {
            break;
        }
        else
        {
            CDACPYDTD(T3, d_arr, d_max, grid.x);
            CDCPYHTDV(int, d_arr_size, grid.x);
            calculateScalar_grid_block(grid.x, grid, block);
            srdsize = block.x * sizeof(T3);
        }
    }

    CDCPYDTH(T3, dest, d_max);

    cudaFree(d_arr);
    cudaFree(d_arr_size);
    cudaFree(d_max);
}

核心思想就是使用cuda多线程的优势,将数组分成多段 每一段同时独立的进行排序 将排序的结果组成一个新的数组 再次将新数组 分段独立排序 直到只剩下一个
因为可以每一段分组可以同时进行排序 在速度上会比cpu更有优势一些

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值