前提:傳統(tǒng)的數(shù)組和矩陣都是通過(guò)numpy來(lái)設(shè)定,然后numpy來(lái)調(diào)用cpu計(jì)算!
cupy的作用:數(shù)組和矩陣都是通過(guò)cupy來(lái)設(shè)定,然后cupy來(lái)調(diào)用gpu并行計(jì)算!
區(qū)別與聯(lián)系:
- 區(qū)別:numpy自動(dòng)調(diào)用cpu來(lái)進(jìn)行"數(shù)組和矩陣間"的計(jì)算,計(jì)算任務(wù)默認(rèn)單進(jìn)程;cupy自動(dòng)調(diào)用gpu來(lái)進(jìn)行"數(shù)組和矩陣間"的計(jì)算,gpu中默認(rèn)并行計(jì)算!
- 聯(lián)系:二者的函數(shù)和實(shí)操的功能基本完全一樣,一般只需把np.xxx()改成cp.xxx()即可。當(dāng)然,cupy還未完全寫完,有些numpy的函數(shù)它還未實(shí)現(xiàn)(基本用不到)。
cupy的優(yōu)勢(shì):專門進(jìn)行大型、高維數(shù)組/矩陣的快速計(jì)算(非常非??欤?!
要想實(shí)現(xiàn)數(shù)組/矩陣的快速運(yùn)算,要注意3點(diǎn):
- 數(shù)組/矩陣的維度、尺寸一定要夠大,計(jì)算量夠大才行,否則gpu的初始化都耗的時(shí)間比計(jì)算時(shí)間都長(zhǎng)!總之:計(jì)算量一定要夠大,最好矢量化編程;
- 數(shù)組/矩陣間的運(yùn)算,比如矩陣相加、相乘、點(diǎn)乘等,一定要直接使用cupy自帶的函數(shù)(如加法:cupy.add(x1,x2))!不要直接寫一個(gè):+ 運(yùn)算符!即:能用自帶函數(shù)就盡量用自帶函數(shù)!
- 一定避免cpu和gpu混合編程:比如在一個(gè)循環(huán)計(jì)算中,每一步循環(huán)中的計(jì)算量不大,但是又有cpu計(jì)算(比如加減乘除賦值等),又用gpu矩陣計(jì)算。此時(shí)用cupy反而會(huì)降低運(yùn)算效率!因?yàn)?cpu和gpu之間的切換、數(shù)據(jù)互通等一系列初始化非常耗時(shí)"(相比計(jì)算任務(wù)來(lái)說(shuō))!
下面用一個(gè)很簡(jiǎn)單的例子即可體現(xiàn)上面的內(nèi)容:循環(huán)矩陣相加
import cupy as cp
import numpy as np
import time
# 高維矩陣/數(shù)組:
gpu = cp.ones( (1024,512,4,4) )
cpu = np.ones( (1024,512,4,4) )
# 純numpy的cpu測(cè)試:
ctime1 = time.time()
for c in range(1024):
cpu = np.add(cpu,cpu) # 這里用np.add()和直接用 + 一樣!內(nèi)核都是cpu來(lái)算
ctime2 = time.time()
ctotal = ctime2 - ctime1
print('純cpu計(jì)算時(shí)間:', ctotal)
# 純cupy的gpu測(cè)試:
gtime1 = time.time()
for g in range(1024):
gpu = cp.add(gpu,gpu) # 自帶的加法函數(shù)
gtime2 = time.time()
gtotal = gtime2 - gtime1
print('純gpu計(jì)算時(shí)間:', gtotal)
# gpu和cpu混合編程:
ggtime1 = time.time()
for g in range(1024):
gpu = gpu + gpu # 手工加法:+ 默認(rèn)回到cpu計(jì)算?。?!
ggtime2 = time.time()
ggtotal = ggtime2 - ggtime1
print('混合的計(jì)算時(shí)間:', ggtotal)
三組循環(huán)矩陣相加的耗時(shí)結(jié)果:
純cpu計(jì)算時(shí)間: 43.857738733291626
純gpu計(jì)算時(shí)間: 0.02496480941772461
混合的計(jì)算時(shí)間: 1.4730699062347412
彼此差距非常明顯!上文中需要注意的2、3點(diǎn)非常非常重要!
由本例也可看出,cupy的gpu并行計(jì)算潛力有多大!
本例的計(jì)算量還是太小,一個(gè)GTX-1050的筆記本顯卡,都根本還沒(méi)發(fā)揮其功力!如果將cupy應(yīng)用到服務(wù)器上、應(yīng)用到深度學(xué)習(xí)之中,潛力非常大!
本文集會(huì)持續(xù)更新cupy的相關(guān)操作,并實(shí)時(shí)將其與對(duì)應(yīng)的numpy使用進(jìn)行對(duì)比。
numpy教程網(wǎng)站
cupy教程網(wǎng)站