偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

CuPy vs. NumPy,使用 GPU 速度提升 10 倍

開發(fā) 開發(fā)工具
CuPy 是由專注于深度學(xué)習(xí)技術(shù)的日本公司 Preferred Networks 開發(fā)的開源庫,旨在提供與 NumPy 兼容的接口,以便使用 CUDA 在 NVIDIA GPU 上執(zhí)行計算。

如果你使用 Numpy 頻率非常高,并且幸運地擁有一臺配備 Nvidia GPU 的系統(tǒng),那么你有一個相對簡單的方法來提升你的計算運行時間。怎么做?很簡單,使用 CuPy Python 庫代替 Numpy。

什么是 Numpy?

我猜你已經(jīng)知道 Numpy Python 庫的全部含義了;否則,你可能不會讀這篇文章。NumPy 是用 C 語言編寫的,它支持快速數(shù)字運算,尤其適用于多維數(shù)組和矩陣,并且它還提供了一系列數(shù)學(xué)函數(shù)來高效地操作這些數(shù)組。

什么是 CuPy,為什么需要它?

CuPy 是由專注于深度學(xué)習(xí)技術(shù)的日本公司 Preferred Networks 開發(fā)的開源庫,旨在提供與 NumPy 兼容的接口,以便使用 CUDA 在 NVIDIA GPU 上執(zhí)行計算。


CUDA(統(tǒng)一計算設(shè)備架構(gòu))是由 NVIDIA 創(chuàng)建的并行計算平臺和應(yīng)用程序編程接口 (API) 模型。它允許軟件開發(fā)人員和軟件工程師使用支持 CUDA 的圖形處理單元 (GPU) 進行通用處理。

CuPy 旨在成為 Numpy 的直接替代品,讓你能夠以最少的代碼更改充分利用 GPU 的并行計算能力。CuPy 的 API 與 NumPy 高度兼容,這意味著在許多情況下,它可以直接替代 Numpy。

至于為什么需要 CuPy,答案很簡單——速度。對于可并行化的操作,CuPy 可以利用 GPU 以比 CPU 更快的速度執(zhí)行計算,尤其是在大規(guī)模數(shù)值計算方面。這對于科學(xué)計算、數(shù)據(jù)分析、機器學(xué)習(xí)、深度學(xué)習(xí)和圖像處理任務(wù)尤其有利。

先決條件

  • Nvidia GPU

首先,你的系統(tǒng)上需要有一塊 Nvidia GPU。在系統(tǒng)提示符下輸入以下命令來檢查你的 GPU。

>>
(base) PS C:\Users\yunduojun> nvidia-smi
Fri Mar 22 11:41:34 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 551.61                 Driver Version: 551.61         CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                     TCC/WDDM  | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4070 Ti   WDDM  |   00000000:01:00.0  On |                  N/A |
| 32%   24C    P8              9W /  285W |     843MiB /  12282MiB |      1%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

如果無法識別nvidia-smi命令(并且你使用的是Nvidia GPU) ,則可能需要安裝驅(qū)動程序。相關(guān)說明請見頁面下方。

此外,你擁有的任何 GPU 都需要具有 3.0 或更高的計算能力。你可以使用以下命令查看 GPU 的計算能力:

$ nvidia-smi --query-gpu=compute_cap --format=csv 
# 在我的系統(tǒng)上輸出以下內(nèi)容
compute_cap 
8.9
  • 安裝 WSL Ubuntu Linux

由于我使用的是 Windows 系統(tǒng),而在該平臺上安裝 Cuda 比較復(fù)雜,因此我選擇在 Linux 下進行安裝。幸運的是,Windows 的 Linux 子系統(tǒng) (WSL) 可以方便地實現(xiàn)這一點。

要在 Windows 上安裝它,請打開 PowerShell 命令窗口,然后輸入:-

(base) PS C:\Users\thoma> wsl --install
Installing: Windows Subsystem for Linux
Windows Subsystem for Linux has been installed.
Installing: Ubuntu
Ubuntu has been installed.
The requested operation is successful. Changes will not be effective until the system is rebooted.

接下來,重啟你的電腦。WSL 應(yīng)該會自動啟動,并要求你設(shè)置用戶名和密碼。如果一切順利,你的命令窗口應(yīng)該如下所示:

圖片圖片

要退出 WSL Linux,請在提示符下輸入exit。在常規(guī) PowerShell 命令窗口中,輸入ubuntu即可返回 Linux Shell。

  • 為你的 GPU 和系統(tǒng)安裝最新的 Nvidia 驅(qū)動程序

轉(zhuǎn)到 Nvidia 網(wǎng)站并安裝與你的系統(tǒng)和 GPU 規(guī)格相關(guān)的最新驅(qū)動程序。www.nvidia.com

  • 在 WSL 上安裝 Miniconda

安裝 WSL 并啟動它后,輸入以下命令來獲取 Miniconda 并安裝它。

$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ ./Miniconda3-latest-Linux-x86_64.sh
  • 安裝 CUDA 工具包

轉(zhuǎn)到CUDA Toolkit 下載頁面并選擇符合你的系統(tǒng)要求和操作系統(tǒng)的版本。

CuPy 的安裝

現(xiàn)在首先設(shè)置我們的 Python 開發(fā)環(huán)境。

#創(chuàng)建我們的測試環(huán)境
(base)$ conda create -n cupy_test pythnotallow= 3.11 -y
# 現(xiàn)在激活它
(base)$ conda activate cupy_test

安裝所需的庫。

(cupy_test) $ conda install -c conda - forge cupy jupyter numpy pandas matplotlib -y

現(xiàn)在在命令提示符中輸入jupyter notebook 。你應(yīng)該會看到瀏覽器中打開了一個 Jupyter Notebook。如果沒有自動打開,你可能會在jupyter notebook 命令后看到一整屏的信息。在屏幕底部附近,會有一個 URL,你應(yīng)該將其復(fù)制并粘貼到瀏覽器中以啟動 Jupyter Notebook。

你的 URL 將與我的不同,但它應(yīng)該看起來像這樣:-

http://127.0.0.1:8888/tree?token=3b9f7bd07b6966b41b68e2350721b2d0b6f388d248cc69da


注意:在下面的時間安排中,我連續(xù)多次運行了 Numpy 和 CuPy 進程,并分別獲得了最佳時間。這確實在一定程度上有利于 CuPy 的運行,因為每次 CuPy 運行的首次調(diào)用都會產(chǎn)生少量開銷,但總的來說,我認為這是一個更公平的比較。

示例 1

一個簡單的數(shù)組數(shù)學(xué)運算。

在此示例中,我們設(shè)置了幾個大型一維數(shù)組,然后對每個數(shù)組元素執(zhí)行簡單的加法運算。請注意,用于 CuPy 處理的數(shù)組是使用 CuPy 而非 NumPy 設(shè)置的。這一點很重要,因為這意味著數(shù)組數(shù)據(jù)將存儲在 GPU 主內(nèi)存中,而不是 CPU 主內(nèi)存中。

import numpy as np 
import cupy as cp 

from timeit import default_timer as timer    

# func1 和 func3 將在 CPU 上運行
def  func1 ( a ):                                  
    for i in  range ( len (a)): 
        a[i]+= 1       
       
# func2 和 func4 將在 GPU 上運行              
def  func2 ( a ):
    for i in  range ( len (a)): 
        a[i]+= 2       
   
def  func3 ( a ):                                  
    a+= 3    
    
def  func4 ( a ):                                  
    a+= 4

if __name__=="__main__": 
    n1 = 300000000                          
    a1 = np.ones(n1, dtype = np.float64) 

    # had to make this array much smaller than
    # the others due to slow loop processing on the GPU
    n2 = 300000                      
    a2 = cp.ones(n2, dtype = cp.float64) 

    n3 = 300000000                           
    a3 = np.ones(n1, dtype = np.float64) 
    n4 = 300000000                      
    a4 = cp.ones(n2, dtype = cp.float64) 
   
    start = timer() 
    func1(a1) 
    print("without GPU/for loop:", timer()-start)     
      
    start = timer() 
    func2(a2) 
    # wait for all calcs to complete
    cp.cuda.Stream.null.synchronize()
    print("with GPU:/for loop", timer()-start) 

    start = timer() 
    func3(a3) 
    print("without GPU:vectorization", timer()-start)     

    start = timer() 
    func4(a4) 
    # wait for all calcs to complete
    cp.cuda.Stream.null.synchronize()
    print("with GPU:vectorization", timer()-start) 
    print()

    print("a1 = ",a1)
    print("a2 = ",a2)
    print("a3 = ",a3)
    print("a4 = ",a4)

輸出如下:

without GPU/for loop: 25.486853414004145
with GPU:/for loop 4.358431388995086
without GPU:vectorization 0.13804959499998404
with GPU:vectorization 0.07079174599994076

a1 =  [2. 2. 2. ... 2. 2. 2.]
a2 =  [3. 3. 3. ... 3. 3. 3.]
a3 =  [4. 4. 4. ... 4. 4. 4.]
a4 =  [5. 5. 5. ... 5. 5. 5.]

需要注意的是,使用 GPU 數(shù)據(jù)的循環(huán)非常慢!盡管 CuPy for 循環(huán)測試的數(shù)組大小是 Numpy 數(shù)組大小的 1/1000,但執(zhí)行時間卻只有 Numpy 的 1/7。

for 循環(huán)將在 CPU 上運行,并導(dǎo)致每次迭代時數(shù)據(jù)在 CPU 和 GPU 之間傳輸,從而加劇性能損失。

相比之下,看看我們?yōu)槭噶炕僮鞴?jié)省的時間。GPU 處理數(shù)據(jù)的速度是 CPU 的兩倍。

如果你嘗試處理不同的數(shù)據(jù)項數(shù)量,你會注意到,隨著數(shù)據(jù)項數(shù)量的減少,GPU 的優(yōu)勢會逐漸減弱。這是可以預(yù)料的,你需要對數(shù)據(jù)進行一些測試,找到一個最佳平衡點,以證明將處理轉(zhuǎn)移到 GPU 所需的額外努力是合理的。

在繼續(xù)下一個示例之前,CuPy 還為類似情況提供了另一種選擇——自定義 CUDA 內(nèi)核。這些內(nèi)核使用類似 C 語言的語法編寫,可以根據(jù)你的需求調(diào)用各種 CuPy 函數(shù)。我們將使用的內(nèi)核函數(shù)是ElementwiseKernel().

我們檢查一下代碼。

import numpy as np 
import cupy as cp 
from timeit import default_timer as timer 

# ElementwiseKernel 函數(shù)
add_five_kernel = cp.ElementwiseKernel( 
    'float64 x' , 
    'float64 y' , 
    'y = x + 5' , 
    'add_five'
 ) 

def  func5 ( a ):
    add_five_kernel(a, a)   # 就地修改

n5 = 300000000
 a5 = cp.ones(n5, dtype=cp.float64) 

start = timer() 
    
func5(a5) 
cp.cuda.Stream.null.synchronize() 
print("with GPU/ElementwiseKernel:" , timer()-start)

在這種情況下,輸出顯示內(nèi)核運行時間介于矢量化 CPU 和矢量化 GPU 操作所需的時間之間。

使用GPU/ElementwiseKernel:0.011662766003923025
 a5 = [ 6.  6.  6. ... 6.  6.  6. ]

有關(guān)可用CuPy 核函數(shù)的完整列表,請查看你所使用版本的文檔。

示例2

稍微復(fù)雜一點的數(shù)組操作。

在此示例中,我們將使用 CuPy 和 Numpy 庫中內(nèi)置的matmul運算進行多維矩陣乘法。每個數(shù)組的大小為 10000 x 10000,包含 1 到 100 之間的隨機浮點數(shù)。

# 首先
import numpy as np 
from timeit import default_timer as timer 

# 設(shè)置種子以實現(xiàn)可重復(fù)性
np.random.seed( 0 ) 

# 生成兩個 10000x10000 的 1 到 100 之間的隨機浮點數(shù)數(shù)組
A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 

# 執(zhí)行矩陣乘法
start = timer() 
C = np.matmul(A, B) 


# 由于矩陣很大,將它們?nèi)看蛴〕鰜聿磺袑嶋H。
# 相反,你可以打印結(jié)果的形狀和一小部分以進行驗證。

print("結(jié)果矩陣的一小部分:\n" , C[:5 , :5]) 
print("不使用 GPU:", timer()-start)

輸出如下

結(jié)果矩陣的一小部分:
[[25461282.56020853 25168348.08695598 25212522.35402665 25303307.69696668 25277886.16204746] 
[25114760.67252064 25197555.19361381 25340074.95867983 25341847.41707999 25373123.1113671 ] 
[25381820.17590097 25326519.29503381 25438611.20780989 25596935.44312112 25538595.65174283] 
[25317284.31091545 25223539.66363661 25272235.85780019 25551426.21236818 25467989.425944 ] 
[25327294.06390036 25527840.32567072 25499601.14864586 25657214.623082 25527855.25691375]]
不使用:3.2115318500000285

現(xiàn)在來看看 CuPy。代碼幾乎一樣;只需更改頂部的導(dǎo)入,并將 cp 替換為 np!

import cupy as cp 

# 設(shè)置種子以實現(xiàn)可重復(fù)性
cp.random.seed(0) 

# 生成兩個 2000x2000 的隨機浮點數(shù)數(shù)組,范圍在 1 到 100 之間
A = cp.random.uniform(low=1.0, high=100.0, size=(10000 , 10000)) 
B = cp.random.uniform(low=1.0, high=100.0, size=(10000 , 10000)) 

# 執(zhí)行矩陣乘法
start = timer() 
C = cp.matmul(A, B) 
# 等待所有計算完成
cp.cuda.Stream.null.synchronize() 


# 由于矩陣很大,將它們?nèi)看蛴〕鰜聿⒉粚嶋H。
# 相反,你可以打印結(jié)果的形狀和一小部分以進行驗證。
print("結(jié)果矩陣的一小部分:\n", C[:5 , :5]) 
print("使用 GPU:", timer()-start)
結(jié)果矩陣的一小部分:
[[25710603.94664048 25421109.27794836 25400571.17687622 25165215.05626292 25729646.95638799] 
[25625453.16519611 25144442.91475235 25222187.53040171 25345612.79231448 25740855.19128766] 
[25341043.05541366 25193877.59648657 25213287.79042915 25105198.56650982 25697665.56022939] 
[25747476.4063573 25303358.1864255 25188271.28090249 25260575.16770762 25653182.98191385] 
[25775006.9423866 25390991.70257155 25475701.8092414 25170055.16207211 25525589.5144844 ]]
使用 GPU:3.991562336000243

等一下!發(fā)生了什么?CuPy 代碼比 Numpy 代碼運行時間更長。這是怎么回事?

我承認我花了一些時間才弄清楚,但最終還是歸結(jié)于內(nèi)存。當(dāng)我們將隨機浮點值分配給數(shù)組時,它們默認設(shè)置為 64 位值。

A.dtype 
dtype( 'float64' )

似乎大多數(shù) GPU 都使用 32 位內(nèi)存寄存器,因此當(dāng)它們處理 64 位數(shù)字時,它們必須做額外的工作,因為每個數(shù)字都會分布在兩個內(nèi)存位置上。至少我是這么認為的。如果有人知道更詳細的信息,請評論告訴我。

現(xiàn)在看看如果我們把數(shù)字的數(shù)據(jù)類型改為 float32 會發(fā)生什么。所以我把這兩行代碼改了

A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 ))

to

A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(np.float32) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(np.float32) 

AND 

A = cp.random.uniform(low= 1.0 , high= 100.0,size=( 10000 , 10000 )) 
B = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 ))

to

A = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(cp.float32) 
B = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(cp.float32)

我重新運行了兩組代碼,以下是輸出。先用 Numpy。

結(jié)果矩陣的一小部分:
[[25461280. 25168348. 25212528. 25303310. 25277886.] 
[25114762. 25197556. 25340074. 25341846. 25373122.] 
[25381818. 25326516. 25438612. 25596934. 25538596.] 
[25317284. 25223536. 25272240. 25551426. 25467992.] 
[25327292. 25527844. 25499604. 25657220. 25527856.]]
不使用 GPU:1.8297855099999651

因此,Numpy 的運行時間幾乎減少了一半,這并不奇怪,因為內(nèi)存需求也減少了一半。

現(xiàn)在看看 CuPy 運行會發(fā)生什么。

結(jié)果矩陣的一小部分:
[[25710616. 25421130. 25400568. 25165210. 25729658.] 
[25625414. 25144374. 25222220. 25345620. 25740910.] 
[25341046. 25193884. 25213314. 25105278. 25697658.] 
[25747516. 25303340. 25188230. 25260598. 25653224.] 
[25775088. 25390888. 25475664. 25170094. 25525540.]]
使用 GPU: 0.14140109800064238

這真是令人印象深刻。不到 0.15 秒的運行時間意味著比 Numpy 快了 10 倍以上。別忘了,NumPy 已經(jīng)超級快了!

我想,歸根結(jié)底,如果你真的需要處理 64 位數(shù)值數(shù)組,那么如果你的 GPU 只支持 32 位內(nèi)存,那么使用 GPU 可能并沒有什么優(yōu)勢。隨著時間的推移,更新、更強大的 GPU 可能會轉(zhuǎn)向 64 位內(nèi)存寄存器。高端 GPU 可能已經(jīng)這么做了。

例3

結(jié)合 CPU 和 GPU 代碼。

有時,并非所有處理都能在 GPU 上完成。一個常見的用例是繪制數(shù)據(jù)圖表。當(dāng)然,你可以使用 GPU 處理數(shù)據(jù),但通常,下一步是查看最終數(shù)據(jù)集的樣子。如果數(shù)據(jù)駐留在 GPU 內(nèi)存中,則無法繪制數(shù)據(jù),因此在調(diào)用繪圖函數(shù)之前,你需要將其移回 CPU 內(nèi)存。將大量數(shù)據(jù)從 GPU 移動到 CPU 是否值得?

現(xiàn)在來一探究竟。

在此示例中,我有一個簡單的 CSV 文件,其中包含日期列和 2016 年至 2018 年的用電量列。我想計算這些日期的用電量平均值、最小值和最大值,然后使用 matplotlib 繪制這些數(shù)據(jù)。這是前幾行的樣子。該文件總共有近 1200 萬條記錄。

DATE,USAGE
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.01
...
...

以下是使用常規(guī) CPU 代碼執(zhí)行此操作的一種方法。

from timeit import default_timer as timer
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime

# 假設(shè) df 是讀取 CSV 后的 DataFrame
 df = pd.read_csv( '/mnt/d/test/D202.csv' , sep= ',' ) 

start = timer() 
df[ 'DATE' ] = pd.to_datetime(df[ 'DATE' ]).dt.date 

# 將 'USAGE' 轉(zhuǎn)換為 NumPy 數(shù)組
usage = df[ 'USAGE' ].values 

# 將 'DATE' 轉(zhuǎn)換為 NumPy 數(shù)組
dates = np.array([date.toordinal() for date in df[ 'DATE' ]]) 

# 查找唯一日期及其索引
unique_dates, indices = np.unique(dates, return_inverse= True ) 

# 初始化數(shù)組來保存最大值、最小值和平均值
max_usage = np.zeros( len (unique_dates)) 
min_usage = np.zeros( len (unique_dates)) 
mean_usage = np.zeros( len (unique_dates)) 

# 計算每個組的最大值、最小值和平均值
for i, date in  enumerate (unique_dates): 
    max_usage[i] = np.max ( usage[indices == i]) 
    min_usage[i] = np. min (usage[indices == i]) 
    mean_usage[i] = np.mean(usage[indices == i]) 

# 將序數(shù)日期轉(zhuǎn)換為日期時間進行繪圖
plot_dates = [datetime.date.fromordinal(date) for date in unique_dates] 

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(plot_dates, mean_usage, label='Mean Usage', marker='o')
plt.plot(plot_dates, max_usage, label='Max Usage', marker='x')
plt.plot(plot_dates, min_usage, label='Min Usage', marker='+')
plt.xlabel('Date')
plt.ylabel('Usage (kWh)')
plt.title('Electric Usage Statistics by Date')
plt.legend()
plt.xticks(rotatinotallow=45)
plt.tight_layout()
plt.show()
print("Finished with CPU at ", timer()-start)

圖片圖片

這是 GPU 等效代碼。

from timeit import default_timer as timer
import pandas as pd
import numpy as np
import cupy as cp
import matplotlib.pyplot as plt
import datetime


# 假設(shè) df 是讀取 CSV 后的 DataFrame
df = pd.read_csv('/mnt/d/test/D202.csv' , sep=',' ) 

start = timer() 
df['DATE'] = pd.to_datetime(df['DATE']).dt.date 

# 將 'USAGE' 轉(zhuǎn)換為 CuPy 數(shù)組
usage = cp.array(df['USAGE'].values) 

# 將 'DATE' 轉(zhuǎn)換為 NumPy 數(shù)組(因為日期處理不是 CuPy 功能)
dates = np.array([date.toordinal() for date in df['DATE']]) 

# 使用 NumPy 查找唯一日期及其索引
# (CuPy 不支持帶有 return_inverse 的 np.unique)
unique_dates, indices = np.unique(dates, return_inverse=True) 

# 初始化數(shù)組以保存 GPU 上的最大值、最小值和平均值
max_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 
min_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 
mean_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 

# 使用 CuPy 計算每個組的最大值、最小值和平均值
for i, date in enumerate(unique_dates): 
    mask = indices == i 
    max_usage[i] = cp.max(usage[mask]) 
    min_usage[i] = cp.min(usage[mask]) 
    mean_usage[i] = cp.mean(usage[mask]) 

# 等待計算完成
cp.cuda.Stream.null.synchronize() 

# 由于 CuPy 不支持繪圖和日期轉(zhuǎn)換,
# 請將結(jié)果轉(zhuǎn)換回 NumPy 以完成這些任務(wù)
max_usage = cp.asnumpy(max_usage) 
min_usage = cp.asnumpy(min_usage) 
mean_usage = cp.asnumpy(mean_usage) 
plot_dates = [datetime.date.fromordinal(date) for date in unique_dates] 

# 繪圖
plt.figure(figsize=(10, 6))
plt.plot(plot_dates, mean_usage, label='Mean Usage', marker='o')
plt.plot(plot_dates, max_usage, label='Max Usage', marker='x')
plt.plot(plot_dates, min_usage, label='Min Usage', marker='+')
plt.xlabel('Date')
plt.ylabel('Usage (kWh)')
plt.title('Electric Usage Statistics by Date')
plt.legend()
plt.xticks(rotatinotallow=45)
plt.tight_layout()
plt.show()
print("Finished with GPU at ", timer()-start)

圖片

這兩組代碼集之間唯一真正的區(qū)別是這 3 行,我們在繪制 CuPy 數(shù)組數(shù)據(jù)之前將其從 GPU 復(fù)制到 CPU。

max_usage = cp.asnumpy(max_usage)
min_usage = cp.asnumpy(min_usage)
mean_usage = cp.asnumpy(mean_usage)

即便如此,CuPy 代碼也比 NumPy 代碼快 70%,因此在這種情況下,這些額外的數(shù)據(jù)復(fù)制步驟的開銷是值得的。

無論如何,我希望本文能夠激發(fā)你研究在工作負載中使用 CuPy 庫和 GPU 的興趣。

記住要測試、測試、再測試。并非所有工作負載都能從切換到基于 GPU 的代碼中受益。有時,你的代碼運行速度可能會變慢,或者任何好處都微不足道,甚至不值得付出努力去實現(xiàn)。嘗試使用 CuPy 代替 NumPy 的一個好處是操作起來很容易。即使它沒有用,你也不會浪費太多時間。

責(zé)任編輯:武曉燕 來源: 數(shù)據(jù)STUDIO
相關(guān)推薦

2021-07-27 10:10:21

CuPyNumpyPython

2023-03-22 13:53:26

芯片英偉達

2024-09-12 22:45:47

2015-03-19 11:03:49

Linuxwin10

2022-10-14 17:30:59

Windows 11微軟

2024-03-19 14:43:17

自動駕駛激光

2024-11-13 09:29:41

SpringCRaCCRIU

2021-01-13 16:04:07

網(wǎng)絡(luò)On-Prem托管

2017-12-06 08:06:47

IBMGPU機器學(xué)習(xí)

2014-09-28 10:29:43

喬布斯施密特Android

2021-12-23 15:36:21

NASSANDAS

2023-05-22 19:49:30

命令Linux

2020-08-25 09:14:17

對象存儲文件存儲塊存儲

2023-10-14 15:22:22

2021-09-30 11:27:58

模型人工智能神經(jīng)網(wǎng)絡(luò)

2019-04-02 15:07:51

API NginxZuul

2011-07-01 10:11:39

2025-02-18 16:00:00

代碼Python架構(gòu)

2021-02-19 18:10:06

微軟WindowsWindows 10

2021-02-19 23:44:27

Windows 10Windows微軟
點贊
收藏

51CTO技術(shù)棧公眾號