美文网首页
用julia GPU进行滚动窗口求和计算:rolling()

用julia GPU进行滚动窗口求和计算:rolling()

作者: 昵称违法 | 来源:发表于2021-06-12 13:51 被阅读0次

    在回测的时候,需要计算很多的指标,对一个时间系列值进行滚动窗口求sum、mean、std......是非常常见的操作,如何提高他们的计算速度呢?

    下面以滚动窗口取40,这些窗口里的系列值再求和,为案例进行。
    主要目的,用于计算时间的对比

    【计算任务】
    1、数组有1亿3千万个元素
    2、rolling windows = 40
    3、function = sum

    【结论】
    1、CPU多线程后,提速10倍,
    2、用GPU计算,比CPU多线程加速10倍
    本机配置:AMD 3700X + RTX 2060

    一、用CPU计算

    (1)单线程计算

    using BenchmarkTools
    
    N = 2^27
    ary =Array(1:N)
    res =similar(ary)
    
    function cpu_fn(ary,res)
        for index in ary
            size = 40
            if index < size
                res[index] = 0 #看业务需求,也可以:有多少就算多少
            else
                for i in index - size + 1 : index
                    res[index] += ary[i]
                end
            end
        end
    
    
        return nothing
    end
    
    @btime cpu_fn(ary,res)  #  4.699s
    

    耗时:4.699s

    (2)多线程计算

    function cpu_fn_threads(ary,res)
        Threads.@threads for index in ary
            size = 40
            if index < size
                res[index] = 0
            else
                for i in index - size + 1 : index
                    res[index] += ary[i]
                end
            end
        end
        return nothing
    end
    
    @btime cpu_fn_threads(ary,res)  #439.207ms   
    

    耗时:439.207ms (接近半秒)

    二、用GPU进行计算

    using CUDA
    using Test
    using BenchmarkTools
    
    function gpu_fn!(ary,res)
        index = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    
        size = 40
        if index < size
            res[index] = 0.0
        else
            for i in index - size + 1 : index
                res[index] += ary[i]
            end
        end
    
        return nothing
    end
    
    N = 2^27
    ary = CUDA.CuArray(1:N)  # a vector stored on the GPU filled with 1.0 (Float32)
    res = CUDA.CuArray(1:N)   # a vector stored on the GPU filled with 2.0
    
    numblocks = ceil(Int, N/256)
    
    @cuda threads=256 blocks=numblocks gpu_fn!(ary,res)
    
    #测试计算时间
    @btime CUDA.@sync begin   # 43.219ms
        @cuda threads=256 blocks=numblocks gpu_fn!(ary,res)
    end
    

    耗时:43.219ms

    三、总结和注意事项

    (1)本机的 CPU是 amd 3700x GPU是 rtx2060

    (2)单线程耗时4.6秒,多线程耗时439.2ms,然而,如果用GPU计算,耗时为43.2ms

    GPU计算时间是CPU多线程的十分之一,是单线程CPU的百分之一,关键是,利用GPU计算后,你可以把CPU解放出来,做别的事情

    (3)同步GPU计算的时候用

    #关键点 是 【begin】  和  【end】,省去begin和end的话,会出错
    CUDA.@sync begin  
        @cuda threads=256 blocks=numblocks gpu_fn!(ary,res)
    end
    

    (4)在GPU上计算sum,mean,std等,你需要查看CUDA提供哪些函数,比如,他没有提供SUM函数,需要自己实现累加,但是提供了sin 、 cos等等,具体可以直接使用哪些函数,请查询CUDA.JL的官网。

    相关文章

      网友评论

          本文标题:用julia GPU进行滚动窗口求和计算:rolling()

          本文链接:https://www.haomeiwen.com/subject/kaxieltx.html