技术开发 频道

nVidia CUDA API(下)

  【IT168 文档】在《nVidia CUDA API(上)》的部分,已經大致說明了 extension 的部分;這邊要來講的則是 runtime library 的部分。

  CUDA 的 runtime library 分成下面三部分:

  common component

  • 提供 CUDA 的 vector 等型別,以及可以同時在 host 及 device 上可以執行的函式。主要包括:
  • 內建的 vector 型別
  • dim3 型別(用於指定 kernel 參數的型別)
  • texture 型別
  • 數學函式

  device component

  在 device 上執行的部分,提供 device 上特殊的函式。主要有:

  • 數學函式。這邊的數學函式是 device 的特殊版本,精確度較低,但是速度較快。
  • 同步函式
  • Atomic 函式
  • 型別轉換函式(Conversion/Casting)
  • texture 函式

  host component

  在 host 上執行的部分,負責控制 device。主要是處理:

  • Device 管理
  • Context 管理(所謂 Context 大致相當於 CPU?)
  • 記憶體管理
  • Code module 管理(Code module 似乎相當於 dynamic library)
  • Execution control
  • Texture reference 管理
  • Interoperability with OpenGL and Direct3D.

  不過,這邊應該就不會列舉了~個別的說明,請參考《CUDA Programming Guide 1.0》這份文件。而這邊,就只大概介紹一些 Heresy 覺得比較會用到的部分了。

  記憶體管理

  要說最重要、一定會用到的部分,應該就是記憶體管理的部分了!因為在 CUDA 中,要在 device 的程式中存取的資料,一定要先存在 device 上,所以在記憶體管理的部分,CUDA 提供了很類似 C 的一些函式:cudaMalloc()、cudaFree()。原則上,cudaMalloc 大致上就是 C 語言中的 malloc,也就像是 C++ 的 new;而 cudaFree 則就相當於 C 的 free,以及 C++ 的 delete。

  而要使用的方法,則是要先宣告 pointer,在 allocate 記憶體給他;下面就是一個簡單的範例:

float    *dev_Array;
cudaMalloc( (
void**)&dev_Array, ArraySize * sizeof( float ) );

   這樣,就可以在 device 上配置一塊大小是 ArraySize 的 float 陣列了~

  如果要把已經存在一般程式中的資料複製到 device 上呢?這時候就要用對應到 C 語言中 memcpy 的函式-cudaMemcpy 了~以 CUDA SDK 範例裡的寫法,會是:

// define, allocate on host
float    *host_Array = new float[100];
for( int i = 0; i < 100; ++ i )
    host_Array[i]
= i;

// define, allocate on device
float    *dev_Array;
cudaMalloc( (
void**)&dev_Array, 100 * sizeof( float ) );

// copy from host to device
cudaMemcpy>( dev_Array, host_Array, 100 * sizeof( float ),
    cudaMemcpyHostToDevice );

   cudaMemcpy 這個函式的四個參數依序為:目標、來源、大小、方法。最後一項方法的型別是 CUDA 的一個列舉型別 cudaMemcpyKind,他有四種值:cudaMemcpyHostToHost, cudaMemcpyHostToDevice, cudaMemcpyDeviceToHost, cudaMemcpyDeviceToDevice;相當直覺的,就是代表由 host/device 複製到 device/host。所以,如果是要反過來把 device 上的資料複製回 host 的話,就只要把最後一項參數改成 cudaMemcpyDeviceToHost 就可以了!

  而要釋放掉 allocate 出來的記憶體空間的話,就直接使用 cudaFree 就可以了。

cudaFree( dev_Array );

   實際上 CUDA 的記憶體管理除了這邊提到的基本類型,還有 cudaMallocPitch(), cudaMemset(), cudaMemcpy2D(), cudaMemcpyToArray(), cudaMemcpyToSymbol() 等其他的記憶體管理函式,在這邊就不一一提出來了。

0
相关文章