python并行计算|pycuda测试、对比及分析

python并行计算|pycuda测试、对比及分析

增量式学习算法能够同时学习网络的节点与参数,但是随着模型结构的增长,计算成本也越来越高,有两个途径可以减少计算所需的时间成本:(1)研究模型划分方法,将比较大的模型划分成几个较小的子模型;(2)通过提高计算机的计算能力(GPU或CPU)。TX2能够利用CUDA进行GPU并行计算,pycuda作为python的并行计算库,可以方便的实现GPU并行加速。本文利用pycuda实现并行加速,并与numpy进行对比。

pycuda实现并行计算

安装、简单使用教程请参照pycuda官网

一个简单的例子

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
import time
from pycuda.compiler import SourceModule
mod = SourceModule('''
__global__ void Text_GPU(float *A , float *B, float *K, size_t N){

    int bid = blockIdx.x;  
    int tid = threadIdx.x;

    __shared__ float s_data[2];

    s_data[tid] = (A[bid*2 + tid] - B[bid*2 + tid]);
    __syncthreads();
    if(tid == 0)
    {
        float sum_d = 0.0;
        for(int i=0;i<N;i++)
        {
            sum_d += (s_data[i]*s_data[i]);
        }
        K[bid] = exp(-sum_d);
    }
}
''')

multiply_them = mod.get_function("Text_GPU")
tic = time.time() 
A = np.random.random((1000,20)).astype(np.float32)
B = np.random.random((1000,20)).astype(np.float32)
K = np.zeros((1000,), dtype=np.float32)
N = 20
N = np.int32(N)   
multiply_them(
        drv.In(A), drv.In(B), drv.InOut(K), N,
        block=(20,1,1), grid=(1000,1))
toc = time.time()
print("time cost is:"+str(toc-tic)) 

time cost:0.00536298751831

注释

grid与block

Block之间通信通过全局内存(Global Memory),同一block下的线程之间可以相互交流通信是通过共享内存(Shared Memory)。每一个线程块都有自己对应的局部内存(Local Memory)。
在这里插入图片描述

SourceModule
mod = SourceModule('''
__global__ void Text_GPU(.....){
......
}
''')

这段代码是C++内核函数,里面定义的是GPU并行计算的主代码。例如:定义两个向量相加的内核函数

mod = SourceModule("""
__global__ void multiply_them(float *dest, float *a, float *b)
{
  const int i = threadIdx.x;
  dest[i] = a[i] + b[i];
}
""")
_shared_ 变量;

定义同一block下的共享内存。

__syncthreads()

同步函数,当以上代码在同一block里都运行完毕后,再执行同步函数下面的代码。

blockIdx.x与threadIdx.x

blockIdx.x取block的ID,threadIdx.x取线程的ID。

与无GPU加速的numpy计算对比

numpy方式一(非for循环)
import numpy as np
import time
A = np.random.random((1000,20)).astype(np.float32)
B = np.random.random((1000,20)).astype(np.float32)
tic = time.time()
dk = A-B
dd = [np.sum(a**2) for a in dk]
K1 = np.exp(-np.array(dd))
toc = time.time()
print("time cost is:"+str(toc-tic))

time cost is:0.0174951553345

numpy方式二(for循环)
import numpy as np
import time
A = np.random.random((1000,20)).astype(np.float32)
B = np.random.random((1000,20)).astype(np.float32)
def Guassion_kernel(x, u):
    d = x-u
    dd = [np.sum(a**2) for a in d]
    return np.exp(-sum(dd))

tic = time.time()

Phi_x = []
for j in range(1000):
    Phi_x.append(Guassion_kernel(A[j], B[j]))
toc = time.time()
print("time cost is:"+str(toc-tic)) 
print(Phi_x)

time cost is:0.0264999866486

对比

表格列出以上三种方式的计算成本。可以看出GPU加速的计算时间成本最低,而带FOR循环计算的计算时间成本最高。这也只是初步的对比,实际应用中,有时GPU加速并不比CPU快。当数据维度很小,况且GPU加速的预配置也是需要额外的计算量,这导致有时带GPU加速的计算时间反而比CPU的要长。

typesGPUCPU without for loopCPU with for loop
time cost0.005362987518310.01749515533450.0264999866486
最后应用在增量式算法中,由于节点的个数是慢慢增加的。三种方式的计算每个迭代步的成本如下图所示。我们发现,运行开始时,节点个较小,GPU计算时间成本比CPU要高,但是后面的,GPU与CPU(…貌似GPU也没有很大优势,主要是节点个数还很少,一百多个节点),我相信随着节点的进一步增加,会更加突现出GPU的有效性。
在这里插入图片描述

结论

本文介绍了pycuda,并实现了python的GPU并行计算。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windSeS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值