2011-08-11 57 views
6

將for循環放入內核是一個壞主意?
或者這是常見的事情嗎?在CUDA內核中放置for循環

+2

這個問題太籠統了,但是如果你乘以矩陣例如,那麼它幾乎是絕對必需的。如果可能的話,你只希望所有的線程都執行相同的代碼。 –

回答

6

將循環放入內核很常見。這並不意味着它總是一個好主意,但也並不意味着它不是。

決定究竟如何有效地分配你的任務和數據,並利用相關的排比的普遍問題是一個很難解決的和問題,特別是當它涉及到CUDA。正在進行積極的研究以有效地確定(即,不盲目探索參數空間)如何對給定的內核實現最佳結果。

有時,它可以使一個很大的意義把環插入內核。例如,對大量常規數據結構的許多元素進行迭代計算,表現出強大的數據獨立性,非常適合於包含循環的內核。其他時候,您可能會決定讓每個線程處理多個數據點,例如,你沒有足夠的共享內存爲每個任務分配一個線程(當大量線程共享大量數據時這並不罕見,並且通過增加每個線程完成的工作量,可以適合所有線程'在共享內存中共享數據)。

最好的辦法是讓一個受過教育的猜測,測試,分析和修改,因爲你需要。有很多空間可以進行優化......啓動參數,全局與常量與共享內存,保持寄存器數量較少,確保合併以及避免內存組衝突等。如果您對性能感興趣,您應該查看NVIDIA®(英偉達™)在CUDA 4.0文檔頁面上提供的「CUDA C最佳實踐」和「CUDA佔用率計算器」(如果您還沒有的話)。

4

如果你小心你的內存訪問模式很普遍沒關係。如果for循環將隨機訪問內存,導致許多未聚合的內存讀取,它可能會非常緩慢。

事實上,我曾經有一段代碼運行的速度較慢與CUDA,因爲我天真地堅持一個在內核中環。但是,一旦我想到了內存訪問,例如通過一次將一個塊加載到共享中,以便每個線程塊都可以在共享的同時執行for循環的一部分,則速度會更快。

0

只要它不在頂層,您應該可以。在頂層執行此操作會否定CUDA的所有優點。

正如丹指出的,內存訪問成爲一個問題。解決這個問題的一個方法是將引用的內存加載到共享內存或紋理內存中(如果它不適合共享)。原因是未合併的全局內存訪問非常緩慢(約400個時鐘週期,而不是共享內存的約40個)。

1
  • 處理大型數據的基本模式是使用一種拼貼方法,其中輸入數據被拆分並且每個線程在其數據的磁貼上工作,其中需要定義一個循環。
    實施例1:如果輸入數據被二維矩陣已知其行數超過其列數我會使用獨特網格塊索引訪問該行和使用利用在所述一個循環平鋪線程索引的方法訪問列瓷磚大小。
    示例2:如果您的線程需要處理進一步計算所需的單個值。 (以矢量規範化爲例),您需要一種拼貼方法,因爲只有在塊內線程才能高效地同步。