CUDA（Compute Unified Devices Architectured，統一計算架構）是由英偉達（NVIDIA）所推出的一種軟硬體整合技術，是該公司對於 GPGPU 的正式名稱。透過這個技術，使用者可利用 NVIDIA 的 GPU 進行影像處理之外的運算，亦是首次可以利用 GPU 作為 C 編譯器的開發環境。CUDA 開發套件（CUDA Toolkit ）只能將自家的 CUDA C 語言（對 OpenCL 只有連結的功能），也就是執行於 GPU 的部分編譯成中間語言或是特定 NVIDIA GPU 架構的機器碼（NVIDIA 官方稱為 device code）；而執行於中央處理器部分的 C C 程式碼（NVIDIA 官方稱為 host code）仍依賴於外部的編譯器，如 Microsoft Windows 下需要 Microsoft Visual Studio；Linux 下則主要依賴於 GCC。 簡介 縮圖 250x250 畫素 CUDA 的資料傳輸 1 將主記憶體的資料傳入 GPU 記憶體 2 CPU 指令驅動 GPU3 GPU 平行運算 4 將運算結果自 GPU 記憶體傳回主記憶體 GPU 不僅用於進行圖形渲染，而且用於物理運算（物理效果如碎片、煙、火、流體）如 PhysX 和 Bullet。進一步的，GPU 可以用在計算生物學與密碼學等領域的非圖形應用上。在 NVIDIA 收購 AGEIA 後，NVIDIA 取得相關的物理加速技術，即是 PhysX 物理引擎。配合 CUDA 技術，顯示卡可以模擬成一顆 PhysX 物理加速晶片。目前，全系列的 GeForce 8 顯示核心都支援 CUDA。而 NVIDIA 亦不會再推出任何的物理加速卡，顯示卡將會取代相關產品。 而使用 CUDA 技術，GPU 可以用來進行通用處理（不僅僅是圖形）；這種方法被稱為 GPGPU。與 CPU 不同的是，GPU 以較慢速度並行大量執行緒，而非快速執行單一執行緒。以 GeForce 8800 GTX 為例，其核心擁有 128 個內處理器。利用 CUDA 技術，就可以將那些內處理器做為執行緒處理器，以解決資料密集的計算。而各個內處理器能夠交換、同步和共享資料。GeForce 8800 GTX 的運算能力可達到 520GFlops，如果建設 SLI 系統，就可以達到 1TFlops。 目前，已有軟體廠商利用 CUDA 技術，研發出 Adobe Premiere Pro 的外掛。透過外掛，使用者就可以利用顯示核心去加速 H264MPEG4 AVC 的編碼速度。速度是單純利用 CPU 作軟體加速的 7 倍左右。 雖然 CUDA 底層是以 CC 為主，並以使用 NVCCNVIDIA 基於 LLVM 的 CC 編譯器介面來進行編譯，但工程師也可以使用編譯器指令（如 OpenACC）以及多種程式設計語言擴充套件對 CUDA 平臺進行操作。如 Fortran 工程師可以使用 CUDA Fortran，或 PGI 公司的 PGI CUDA Fortran 編譯器進行編譯。除了此之外 CUDA 平臺還支援其它計算介面，如 Khronos Group 的 OpenCL，Microsoft 的 DirectCompute，以及 CAMP。也可以透過其他語言如 Python，Perl，Java，Ruby，Lua，Haskell，MATLAB，IDL 及 Mathematica 的介面間接呼叫 CUDA。 CUDA 最初的 CUDA 軟體發展包（SDK）於 2007 年 2 月 15 日公佈，同時支援 Microsoft Windows 和 Linux。而後在第二版中加入對 Mac OS X 的支援 但於 CUDA Toolkit 102 起放棄對 macOS 的支援，取代 2008 年 2 月 14 日釋出的測試版。所有 G8x 系列及以後的 NVIDIA GPUs 皆支援 CUDA 技術，包括 GeForce，Quadro 和 Tesla 系列。CUDA 與大多數標準作業系統相容。Nvidia 宣告：根據二進位相容性，基於 G8x 系列開發的程式無需修改即可在未來所有的 Nvidia 顯示卡上執行。 優點 在 GPUs（GPGPU）上使用圖形 APIs 進行傳統通用計算，CUDA 技術有下列幾個優點： 分散讀取 程式碼可以從記憶體的任意位址讀取 統一虛擬記憶體（Unified Memory 從 CUDA 60 開始） 將所有 CPU 和 GPU 的記憶體置於統一管理的虛擬記憶體空間下。 共用記憶體（Global Memory） 存取快速的區域，使之在多個執行緒間共用，有效頻寬比紋理記憶體（Texture Memory）更大。 與 GPU 之間更快的下載與回讀 全面支援整型與位操作，包括整型紋理查詢 限制 CUDA 不支援完整的 C 語言標準。它在 C 編譯器上執行主機程式碼時，會使一些在 C 中合法（但在 C 中不合法）的程式碼無法編譯。 不支援紋理渲染（CUDA 32 及以後版本透過在 CUDA 陣列中引入 表面寫操作 底層的不透明資料結構 來進行處理） 受系統主線的頻寬和延遲的影響，主機與裝置記憶體之間資料複製可能會導致效能下降（透過 GPU 的 DMA 引擎處理，非同步記憶體傳輸可在一定範圍內緩解此現象） 當執行緒總數為數千時，執行緒應按至少 32 個一組來執行才能獲得最佳效果。如果每組中的 32 個執行緒使用相同的執行路徑，則程式分支不會顯著影響效果；在處理本質上不同的任務時，單指令流多資料流執行模型將成為一個瓶頸（如在光線追蹤演演算法中遍歷一個空間分割的資料結構） 只有 NVIDIA 的 GPUs 支援 CUDA 技術 由於編譯器需要使用最佳化技術來利用有限的資源，即使合法的 CC 有時候也會被標記並中止編譯 CUDA（計算能力 1x）使用一個不包含遞迴、函式指標的 C 語言子集，外加一些簡單的擴充套件。而單個程序必須執行在多個不相交的記憶體空間上，這與其它 C 語言執行環境不同。 CUDA（計算能力 2x）允許 C 類功能的子集，如成員函式可以不是虛擬的（這個限制將在以後的某個版本中移除）參見《CUDA C 程式設計指南 31》－附錄 D6 雙精度浮點（CUDA 計算能力 13 及以上）與 IEEE754 標準有所差異：倒數、除法、平方根僅支援舍入到最近的偶數。單精確度中不支援反常值（denormal）及 sNaN（signaling NaN）；只支援兩種 IEEE 舍入模式（舍位與舍入到最近的偶數），這些在每條指令的基礎上指定，而非控制字碼；除法 平方根的精度比單精確度略低。 顯示卡的受支援情況 不同 CUDA 版本支援的計算能力列表 CUDA 版本 支援的計算能力 微架構 備註 10 10 11 11 10 11x 20 10 11x 21 231 10 13 30 31 10 20 Fermi 32 10 21 Fermi 40 42 10 21x Fermi 50 55 10 35 Fermi Kepler 60 10 35 Fermi Kepler 65 11 5x Fermi Kepler 最後支援計算能力 1x 的版本 70 75 20 5x Fermi Kepler 80 20 6x Fermi Kepler Pascal 最後支援計算能力 2x Fermi 的版本；GTX 1070Ti 不受支援 90 92 30 72 Kepler Pascal Volta Pascal GTX 1070Ti 不受 CUDA SDK 90 支援，但受 CUDA SDK 92 支援 100 102 30 75 Kepler Pascal Volta Turing 最後支援計算能力 3x Kepler 的版本；CUDA SDK 102 是最後能用於 macOS 的官方版本，在未來的版本中 macOS 將不被支援 110 35 86 Pascal Volta Turing Ampere 不同計算能力對應的顯示卡列表 計算能力（版本） 微架構 GPU GeForce 系列 Quadro NVS 系列 Tesla 系列 Tegra 系列，Jetson 系列，DRIVE 系列 10 G80 GeForce 8800 Ultra GeForce 8800 GTX GeForce 8800 GTS G80 Quadro FX 5600 Quadro FX 4600 Quadro Plex 2100 S4 Tesla C870 Tesla D870 Tesla S870 11 G92 G94 G96 G98 G84 G86 GeForce GTS 250 GeForce 9800 GX2 GeForce 9800 GTX GeForce 9800 GT GeForce 8800 GTS G92 GeForce 8800 GT GeForce 9600 GT GeForce 9500 GT GeForce 9400 GT GeForce 8600 GTS GeForce 8600 GT GeForce 8500 GTGeForce G110M GeForce 9300M GS GeForce 9200M GS GeForce 9100M G GeForce 8400M GT GeForce G105M Quadro FX 4700 X2 Quadro FX 3700 Quadro FX 1800 Quadro FX 1700 Quadro FX 580 Quadro FX 570 Quadro FX 470 Quadro FX 380 Quadro FX 370 Quadro FX 370 Low Profile Quadro NVS 450 Quadro NVS 420 Quadro NVS 290 Quadro NVS 295 Quadro Plex 2100 D4Quadro FX 3800M Quadro FX 3700M Quadro FX 3600M Quadro FX 2800M Quadro FX 2700M Quadro FX 1700M Quadro FX 1600M Quadro FX 770M Quadro FX 570M Quadro FX 370M Quadro FX 360M Quadro NVS 320M Quadro NVS 160M Quadro NVS 150M Quadro NVS 140M Quadro NVS 135M Quadro NVS 130M Quadro NVS 450 Quadro NVS 420 Quadro NVS 295 12 GT218 GT216 GT215 GeForce GT 340 GeForce GT 330 GeForce GT 320 GeForce 315 GeForce 310 GeForce GT 240 GeForce GT 220 GeForce 210GeForce GTS 360M GeForce GTS 350M GeForce GT 335M GeForce GT 330M GeForce GT 325M GeForce GT 240M GeForce G210M GeForce 310M GeForce 305M Quadro FX 380 Low Profile Quadro FX 1800M Quadro FX 880M Quadro FX 380MNvidia NVS 300 NVS 5100M NVS 3100M NVS 2100M ION 13 GT200 GT200b GeForce GTX 295 GTX 285 GTX 280 GeForce GTX 275 GeForce GTX 260 Quadro FX 5800 Quadro FX 4800 Quadro FX 4800 for Mac Quadro FX 3800 Quadro CX Quadro Plex 2200 D2 Tesla C1060 Tesla S1070 Tesla M1060 20 GF100 GF110 GeForce GTX 590 GeForce GTX 580 GeForce GTX 570 GeForce GTX 480 GeForce GTX 470 GeForce GTX 465GeForce GTX 480M Quadro 6000 Quadro 5000 Quadro 4000 Quadro 4000 for Mac Quadro Plex 7000Quadro 5010M Quadro 5000M Tesla C2075 Tesla C2050C2070 Tesla M2050M2070M2075M2090 21 GF104 GF106 GF108 GF114 GF116 GF117 GF119 GeForce GTX 560 Ti GeForce GTX 550 Ti GeForce GTX 460 GeForce GTS 450 GeForce GTS 450 GeForce GT 640 GDDR3 GeForce GT 630 GeForce GT 620 GeForce GT 610 GeForce GT 520 GeForce GT 440 GeForce GT 440 GeForce GT 430 GeForce GT 430 GeForce GT 420GeForce GTX 675M GeForce GTX 670M GeForce GT 635M GeForce GT 630M GeForce GT 625M GeForce GT 720M GeForce GT 620M GeForce 710M GeForce 610M GeForce 820M GeForce GTX 580M GeForce GTX 570M GeForce GTX 560M GeForce GT 555M GeForce GT 550M GeForce GT 540M GeForce GT 525M GeForce GT 520MX GeForce GT 520M GeForce GTX 485M GeForce GTX 470M GeForce GTX 460M GeForce GT 445M GeForce GT 435M GeForce GT 420M GeForce GT 415M GeForce 710M GeForce 410M Quadro 2000 Quadro 2000D Quadro 600Quadro 4000M Quadro 3000M Quadro 2000M Quadro 1000MNVS 310 NVS 315 NVS 5400M NVS 5200M NVS 4200M 30 Kepler GK104 GK106 GK107 GeForce GTX 770 GeForce GTX 760 GeForce GT 740 GeForce GTX 690 GeForce GTX 680 GeForce GTX 670 GeForce GTX 660 Ti GeForce GTX 660 GeForce GTX 650 Ti BOOST GeForce GTX 650 Ti GeForce GTX 650GeForce GTX 880M GeForce GTX 780M GeForce GTX 770M GeForce GTX 765M GeForce GTX 760M GeForce GTX 680MX GeForce GTX 680M GeForce GTX 675MX GeForce GTX 670MX GeForce GTX 660M GeForce GT 750M GeForce GT 650M GeForce GT 745M GeForce GT 645M GeForce GT 740M GeForce GT 730M GeForce GT 640M GeForce GT 640M LE GeForce GT 735M GeForce GT 730M Quadro K5000 Quadro K4200 Quadro K4000 Quadro K2000 Quadro K2000D Quadro K600 Quadro K420Quadro K500M Quadro K510M Quadro K610M Quadro K1000M Quadro K2000M Quadro K1100M Quadro K2100M Quadro K3000M Quadro K3100M Quadro K4000M Quadro K5000M Quadro K4100M Quadro K5100MNVS 510 Quadro 410 Tesla K10 GRID K340 GRID K520 32 Kepler GK20A Tegra K1Jetson TK1 35 Kepler GK110 GK208 GeForce GTX Titan Z GeForce GTX Titan Black GeForce GTX Titan GeForce GTX 780 Ti GeForce GTX 780 GeForce GT 640 GDDR5 GeForce GT 630 v2 GeForce GT 730 GeForce GT 720 GeForce GT 710 GeForce GT 740M 64bit DDR3 GeForce GT 920M Quadro K6000 Quadro K5200 Tesla K40 Tesla K20x Tesla K20 37 Kepler GK210 Tesla K80 50 GM107 GM108 GeForce GTX 750 Ti GeForce GTX 750 GeForce GTX 960M GeForce GTX 950M GeForce 940M GeForce 930M GeForce GTX 860M GeForce GTX 850M GeForce 845M GeForce 840M GeForce 830M GeForce GTX 870M Quadro K1200 Quadro K2200 Quadro K620 Quadro M2000M Quadro M1000M Quadro M600M Quadro K620M NVS 810 Tesla M10 52 GM200 GM204 GM206 GeForce GTX Titan X GeForce GTX 980 Ti GeForce GTX 980 GeForce GTX 970 GeForce GTX 960 GeForce GTX 950 GeForce GTX 750 SEGeForce GTX 980M GeForce GTX 970M GeForce GTX 965M Quadro M6000 24GB Quadro M6000 Quadro M5000 Quadro M4000 Quadro M2000 Quadro M5500Quadro M5000M Quadro M4000M Quadro M3000M Tesla M4 Tesla M40 Tesla M6 Tesla M60 53 GM20B Tegra X1Jetson TX1Jetson NanoDRIVE CXDRIVE PX 60 Pascal GP100 Quadro GP100 Tesla P100 61 Pascal GP102 GP104 GP106 GP107 GP108 Nvidia TITAN Xp Titan XGeForce GTX 1080 Ti GTX 1080 GTX 1070 Ti GTX 1070 GTX 1060 GTX 1050 Ti GTX 1050GT 1030 MX350 MX330 MX250 MX230 MX150 Quadro P6000 Quadro P5000 Quadro P4000 Quadro P2200 Quadro P2000 Quadro P1000 Quadro P400 Quadro P500 Quadro P520 Quadro P600Quadro P5000 Mobile Quadro P4000 Mobile Quadro P3000 Mobile Tesla P40 Tesla P6 Tesla P4 62 Pascal GP10B Tegra X2 Jetson TX2 DRIVE PX 2 70 Volta GV100 NVIDIA TITAN V Quadro GV100 Tesla V100 Tesla V100S 72 Volta GV10BNvidia Xavier Specs on TechPowerUp preliminary Tegra XavierJetson Xavier NX Jetson AGX Xavier DRIVE AGX Xavier DRIVE AGX Pegasus 75 Turing TU102 TU104 TU106 TU116 TU117 NVIDIA TITAN RTXGeForce RTX 2080 Ti RTX 2080 Super RTX 2080 RTX 2070 Super RTX 2070 RTX 2060 Super RTX 2060GeForce GTX 1660 Ti GTX 1660 Super GTX 1660 GTX 1650 Super GTX 1650 GeForce MX450 Quadro RTX 8000 Quadro RTX 6000 Quadro RTX 5000 Quadro RTX 4000Quadro T2000 Quadro T1000 Tesla T4 80 Ampere GA100 GA102 GA104 GA106 NVIDIA Geforce RTX 3090 Geforce RTX 3080 RTX 3070 RTX 3060Ti RTX 3060 A100 僅限 OEM 產品 詳情請參見 Nvidia 應用 利用 CUDA 技術，配合適當的軟體（例如 MediaCoder、Freemake Video Converter），就可以利用顯示核心進行高畫質影片編碼加速。影片解碼方面，同樣可以利用 CUDA 技術實現。此前，NVIDIA 的顯示核心本身已整合 PureVideo 單元。可是，實現相關加速功能的一個微軟 API－DXVA，偶爾會有加速失效問題。所以利用 CoreAVC 配合 CUDA，變相在顯示核心上實現軟體解碼，解決相容性問題。另外，配合適當的引擎，顯示核心就可以計算光線跟蹤。NVIDIA 就放出了自家的 Optix 即時光線跟蹤引擎，透過 CUDA 技術利用 GPU 計算光線跟蹤。 支援的產品 所有基於 G80 及之後架構的民用與專業顯示卡或運算模組皆支援 CUDA 技術。 示例 CUDA Driver API 下面將示範以最底層的 CUDA Driver API 呼叫 GPU 做列向量的加法，以下為 CPU 端的程式碼 本範例修改自 Andrei de A Formiga 20120604 寫的範例 httpsgistgithubcomtautologico2879581 編譯指令 nvcc O3 lcuda addc o addexe include stdioh include stdlibh include cudah include builtin_typesh Driver api 的型態定義 define N 1024 列向量長度 利用 CUDA 函式的錯誤傳回做例外處理 inline void checkCudaErrors CUresult err if CUDA_SUCCESS err printf CUDA Driver API error 04d from file s line in err __FILE__ __LINE__ exit 1 直接終止程式 CUdevice device CUDA 裝置 也就是 GPU 物件 CUcontext context CUDA 內容物件 CUmodule module 代表 GPU 程式碼的物件 CUfunction function CUDA GPU 函式 size_t totalGlobalMem CUDA 裝置記憶體總量 Driver API 只能自外部檔案讀取 GPU 程式，可以為 PTX 中間碼也可以是 cubin 機器碼 或是混合各種架構機器碼的 fatbin char module_file char matSumKernelcubin GPU 函式名稱 char kernel_name char matSum 初始化 CUDA 的手續 void initCUDA int deviceCount 0 當前可使用的 CUDA 裝置 GPU 數 CUresult err cuInit 0 初始化 CUDA API if err CUDA_SUCCESS 取得可用裝置數 checkCudaErrors cuDeviceGetCount deviceCount if deviceCount 0 確定有可用的裝置 fprintf stderr Error no devices supporting CUDAn exit 1 get first CUDA device checkCudaErrors cuDeviceGet device 0 取編號為 0 的裝置 char name 100 cuDeviceGetName name 100 device 印出裝置名稱 printf Using device 0 sn name checkCudaErrors cuDeviceTotalMem totalGlobalMem device 印出裝置可用記憶體 printf Total amount of global memory llu bytesn unsigned long long totalGlobalMem GPU 記憶體是否是為 64bits 定址 printf 64bit Memory Address sn totalGlobalMem unsigned long long 4102410241024L YES NO 建立 CUDA 內容 err cuCtxCreate context 0 device if err CUDA_SUCCESS fprintf stderr Error initializing the CUDA contextn cuCtxDetach context exit 1 讀取編譯好的 cubin GPU 程式碼 err cuModuleLoad module module_file if err CUDA_SUCCESS fprintf stderr Error loading the module sn module_file cuCtxDetach context 釋放 CUDA 內容物件 exit 1 獲取 GPU 程式裡函式 matSum 的指標 err cuModuleGetFunction function module kernel_name if err CUDA_SUCCESS fprintf stderr Error getting kernel function sn kernel_name cuCtxDetach context exit 1 int main int argc char argv int a N b N c N CUdeviceptr d_a d_b d_c 注意 GPU 變數指標的型態是 CUdeviceptr typedef unsigned int CUdeviceptr_v2 typedef CUdeviceptr_v2 CUdeviceptr 初始化主記憶體變數 for int i 0 i N i a i i b i N i initCUDA 動態分配 GPU 記憶體 CUresult cuMemAlloc CUdeviceptr dptr size_t bytesize checkCudaErrors cuMemAlloc d_a sizeof int N checkCudaErrors cuMemAlloc d_b sizeof int N checkCudaErrors cuMemAlloc d_c sizeof int N 將列向量傳入裝置 CUresult cuMemcpyHtoD CUdeviceptr dstDevice const void srcHost size_t ByteCount checkCudaErrors cuMemcpyHtoD d_a a sizeof int N checkCudaErrors cuMemcpyHtoD d_b b sizeof int N void args 3 d_a d_b d_c 包裝放入 GPU 函式的引數 執行 GPU 函式 CUresult cuLaunchKernel CUfunction f unsigned int gridDimX unsigned int gridDimY unsigned int gridDimZ unsigned int blockDimX unsigned int blockDimY unsigned int blockDimZ unsigned int sharedMemBytes CUstream hStream void kernelParams void extra checkCudaErrors cuLaunchKernel function N 1 1 Nx1x1 blocks 1 1 1 1x1x1 threads 0 0 args 0 將運算結果送回主記憶體 CUresult cuMemcpyDtoH void dstHost CUdeviceptr srcDevice size_t ByteCount checkCudaErrors cuMemcpyDtoH c d_c sizeof int N 將 CPU 和 GPU 運算結果做對照 for int i 0 i N i if c i a i b i printf Error at array position d Expected d Got dn i a ib i c i 釋放 GPU 記憶體 CUresult cuMemFree CUdeviceptr dptr checkCudaErrors cuMemFree d_a checkCudaErrors cuMemFree d_b checkCudaErrors cuMemFree d_c cuCtxDetach context 釋放 CUDA 內容物件 return 0 而以下是 GPU 端的程式碼 本範例修改自 Andrei de A Formiga 20120604 寫的範例 httpsgistgithubcomtautologico2879581 此部分要先編譯成 cubin 後才可以被 CPU 端程式使用 編譯指令 nvcc O3 cubin archnative matSumKernelcu o matSumKernelcubin define N 1024 列向量長度 extern C __global__ void matSum int a int b int c int tid blockIdxx thread 的 x 座標 if tid N c tid a tid b tid 每個 thread 做一次加法 CUDA Runtime API 下列的範例是以相較於 Driver API 來說比較簡便的 CUDA Runtime API 做列向量的加法： 本範例修改自 Nvidia 官方的 CUDA 開發指引 httpsdocsnvidiacomcudacudacprogrammingguideindexhtmlkernels 編譯指令 nvcc vector_addcu archnative o vector_addexe archnative 代表將 device code 編譯成當前電腦 Nvidia GPU 架構的機器碼，拿掉就是照預設編譯成 PTX 中間碼。 include stdioh include stdlibh 引用動態分配 malloc、隨機函式 rand 和隨機上限 RAND_MAX define N 1024 列向量長度 Device code 送入 GPU 執行的部分 __global__ void VecAdd float A float B float C int i threadIdxx thread 的 x 座標 if i NC i A i B i 每個 thread 作一次加法 Host code 送入 CPU 執行的部分 int main size_t size N sizeof float 向量的實際大小，以位元組 bytes 為單位 int i 迴圈計數 動態分配位於 host CPU 記憶體 的向量 float h_A float malloc size float h_B float malloc size float h_C float malloc size 隨機初始化輸入向量 for i 0 i N ih_A i float rand float RAND_MAX h_B i float rand float RAND_MAX 動態分配位於 device GPU 記憶體 的向量 float d_A cudaMalloc d_A size cudaError_t cudaMalloc void devPtr size_t size float d_B cudaMalloc d_B size float d_C cudaMalloc d_C size 將向量從 CPU 複製到 GPU cudaMemcpy d_A h_A size cudaMemcpyHostToDevice cudaMemcpy d_B h_B size cudaMemcpyHostToDevice 將 device code 送入 GPU 並執行，執行時一個 Grid 只有一個 block ，一個 block 有 N 個 thread VecAdd1 Nd_A d_B d_C 將算好的向量從 GPU 複製到 CPU cudaMemcpy h_C d_C size cudaMemcpyDeviceToHost 印出運算結果 for i 0 i N iprintf f h_C i 釋放 GPU 記憶體 cudaFree d_A cudaFree d_B cudaFree d_C 釋放 CPU 記憶體 free h_A free h_B free h_C Python 以下以 pycuda ，間接呼叫 CUDA 做列向量的阿達瑪乘積 也就是元素間乘積而非內積 import pycudadriver as drv CUDA drivers import pycudaautoinit 自動初始化 CUDA import numpy 矩陣運算 讀取並編譯 GPU 執行的程式碼，以 CUDAC 寫成 mod drvSourceModule __global__ void multiply_them float c float a float b int i threadIdxx c i a i b i 獲取 GPU 程式碼中的 multiply_them 函式 multiply_them modget_function multiply_them 生成兩個常態隨機分佈的浮點數 ndarray，shape 為 400 h_a numpyrandomrandn 400astype numpyfloat32 h_b numpyrandomrandn 400astype numpyfloat32 儲存結果的 h_c 列向量，其 shape 和向量 a 相同但值為零 h_c numpyzeros_like a 執行 GPU 的函式 注意這裡 h_a h_b 和 h_c 是在 CPU 記憶體的 python 變數 以下按照原來 GPU 程式碼的區域變數順序，指定哪些是從 CPU 傳入 GPU drvIn；哪些是從 GPU 傳入 CPU drvOut， 簡單來說，自 GPU 傳出到 h_c； h_a 傳入 GPU；h_b 傳入 GPU。 40011 代表一個 block 裡有的 thread 數量為 400 x 1 x 1 multiply_them drvOut h_c drvIn h_a drvIn h_b block40011 印出結果 print d_c 也可以用 pycublas 間接呼叫 CUDA ，來計算矩陣乘法 import numpy from pycublas import CUBLASMatrix 以 numpy 定義矩陣並傳入 CUBLASMatrix A CUBLASMatrix numpymat 123456numpyfloat32 B CUBLASMatrix numpymat 234567numpyfloat32 以 CUBLASMatrix 做矩陣乘法 C AB 將運算結果轉回 numpy 並印出 print Cnp_mat 相關條目 OpenCL Vulkan 參考文獻 外部連結 Category 英偉達 Category 顯示卡 Category 併發計算 Category 物理引擎 CategoryGPGPU