CUDA

概要

以GeForce 8800 GTX為例，其核心擁有128個內處理器。利用CUDA技術，就可以將那些內處理器串通起來，成為執行緒處理器去解決資料密集的計算。而各個內處理器能夠交換、同步和共用資料。利用NVIDIA的C-編譯器，通過驅動程式，就能利用這些功能。亦能成為流處理器，讓應用程式利用進行運算。
GeForce 8800 GTX顯示卡的運算能力可達到520GFlops，如果建設SLI系統，就可以達到1TFlops。 
但程式設計師在利用CUDA技術時，須分開三種不同的記憶體，要面對繁複的執行緒層次，編譯器亦無法自動完成多數任務，以上問題就提高開發難度。而將來的G100會採用第二代的CUDA技術，提高效率，降低開發難度。
目前，已有軟體廠商利用CUDA技術，研發出Adobe Premiere Pro的外掛程式。通過外掛程式，使用者就可以利用顯示核心去加速H.264/MPEG-4 AVC的編碼速度。速度是單純利用CPU作軟體加速的7倍左右。
在NVIDIA收購AGEIA後，NVIDIA取得相關的物理加速技術，即是PhysX物理引擎。配合CUDA技術，顯示卡可以類比成一顆PhysX物理加速晶片。目前，全系列的GeForce 8顯示核心都支援CUDA。而NVIDIA亦不會再推出任何的物理加速卡，顯示卡將會取代相關產品。
為了將CUDA推向民用，NVIDIA舉行一系列的編程比賽，要求參賽者開發程式，充分利用CUDA的計算潛能。但是，要將GPGPU普及化，還要看微軟能否在Windows作業系統中，提供相關的編程埠。
2008年8月，NVIDIA推出CUDA 2.0。2010年3月22日，NVIDIA推出CUDA 3.0，僅支援Fermi及之後的架構。
CUDA是一種由NVIDIA提出的並由其製造的圖形處理單元（GPUs）實現的一種平行計算平臺及程式設計模型。CUDA給程式開發人員提供直接存取CUDA GPUs中的虛擬指令集和平行計算元件的記憶體。
使用CUDA技術，GPUs可以用來進行通用處理（不僅僅是圖形）；這種方法被稱為GPGPU。與CPUs不同的是，GPUs有著側重以較慢速度執行大量併發執行緒的並行流架構，而非快速執行單一執行緒。
軟體發展者可以通過CUDA加速庫，編譯器指令（如OpenACC）以及符合工業標準的程式設計語言（如C,C++和Fortran）擴展對CUDA平臺進行操作。C/C++程式師可以使用「CUDA C/C++」，使用「NVCC」——NVIDIA基於LLVM的C/C++編譯器進行編譯；Fortran程式師可以使用「CUDA Fortran」，使用PGI公司的PGI CUDA Fortran編譯器進行編譯。除了庫、編譯器指令、CUDA C/C++和CUDA Fortran，CUDA平臺還支援其它計算介面，如Khronos Group的OpenCL，Microsoft的DirectCompute，以及C++AMP。其協力廠商封裝也可用於Python，Perl，Fortran，Java，Ruby，Lua，Haskell，MATLAB，IDL及Mathematica的原生支援。
在電腦遊戲行業中，GPUs不僅用於進行圖形彩現，而且用於遊戲物理運算（物理效果如碎片、煙、火、流體），比如PhysX和Bullet。在計算生物學與密碼學等領域的非圖形應用上，CUDA的加速效果達到可以用數量級來表示的程度。
CUDA同時提供底層API與高階API。最初的CUDA軟體發展包（SDK）於2007年2月15日公布，支援Microsoft Windows和Linux。而後在第二版中加入對Mac OS X的支援，取代2008年2月14日發布的測試版。所有G8x系列及以後的NVIDIA GPUs皆支援CUDA技術，包括GeForce，Quadro和Tesla系列。CUDA與大多數標準作業系統相容。Nvidia聲明：根據二進位相容性，基於G8x系列開發的程式無需修改即可在未來所有的Nvidia顯卡上運行。

應用

利用CUDA技術，配合適當的軟體（例如MediaCoder、Freemake Video Converter），就可以利用顯示核心進行高畫質影片編碼加速。影片解碼方面，同樣可以利用CUDA技術實現。此前，NVIDIA的顯示核心本身已整合PureVideo單元。可是，實現相關加速功能的一個微軟API－DXVA，偶爾會有加速失效問題。所以利用CoreAVC配合CUDA，變相在顯示核心上實現軟體解碼，解決相容性問題。另外，配合適當的引擎，顯示核心就可以計算光線跟蹤。NVIDIA就放出了自家的Optix實時光線跟蹤引擎，透過CUDA技術利用GPU計算光線跟蹤。

支援的產品

所有基於G80及之後架構的民用與專業顯示卡或運算模組皆支援CUDA技術。

範例

下列的範例是如何用C++自GPU的image陣列中取得紋理（texture）：
cudaArray* cu_array;texture<float, 2> tex;// Allocate arraycudaChannelFormatDesc description = cudaCreateChannelDesc<float>();cudaMallocArray(&cu_array, &description, width, height);// Copy image data to arraycudaMemcpy(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);// Bind the array to the texturecudaBindTextureToArray(tex, cu_array);// Run kerneldim3 blockDim(16, 16, 1);dim3 gridDim(width / blockDim.x, height / blockDim.y, 1);kernel<<< gridDim, blockDim, 0 >>>(d_odata, height, width);cudaUnbindTexture (tex);__global__ void kernel(float* odata, int height, int width){
   unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
   float c = tex2D(tex, x, y);
   odata[y*width+x] = c;}
下列的例子是用Python改寫. Python相關的訊息可取自PyCUDA.
import pycuda.driver as drvimport numpyimport pycuda.autoinitmod = drv.SourceModule("""__global__ void multiply_them(float *dest, float *a, float *b){  const int i = threadIdx.x;  dest[i] = a[i] * b[i];}""")multiply_them = mod.get_function("multiply_them")a = numpy.random.randn (400).astype(numpy.float32)b = numpy.random.randn (400).astype(numpy.float32)dest = numpy.zeros_like (a)multiply_them(
        drv.Out(dest), drv.In(a), drv.In(b),
        block=(400,1,1))print dest-a*b
更多的Python的矩陣相乘問題可取自pycublas.
import numpyfrom pycublas import CUBLASMatrixA = CUBLASMatrix(numpy.mat([[1,2,3],[4,5,6]],numpy.float32))B = CUBLASMatrix(numpy.mat([[2,3],[4,5],[6,7]],numpy.float32))C = A*Bprint C.np_mat()