CUDA顯卡運算編程菜鳥入門指南1——Hello world - yfszzx的專欄 - 博客頻道 - CSDN.NET


 第一次知道有顯卡(GPU)編程這個東西,是去年比特幣最熱門的時候,看了幾篇關於比特幣的文章,說比特幣挖礦要靠顯卡,CPU的速度與GPU根本就沒法比,於是就非常好奇,顯卡是什么神奇的東西?為什么運算速度會比CPU快很多?當時也只是好奇而已,根本沒想過這東西會與自己有任何關系。

去年年底的時候,我開始研究機器學習,試着用PHP編了幾個遺傳算法和神經網絡算法的程序,發現很有趣,功能很強大,我一直想做醫學方面的人工智能開發,覺得機器學習這個東西很有用,但就是運算速度太慢,估算了一下按程序的運行速度,要初略的解決我的問題至少要算一兩個星期,如果要以較高的精確度解決我的問題,可能要算幾個月。仔細權衡利弊之后,我決定從頭學C語言,畢竟C是高級語言中運算速度最快的(現在后悔,當時要從C++開始學就更好了)。從初學到把我的php程序改寫為C,一共花了兩個星期左右,可喜的是運算速度提高了大約150倍。

后來發現神經網絡用遺傳算法來驅動遠不如用退火算法驅動效率高,並且神經網絡算法可以有很多冗余計算可以去掉,這樣一來,我的算法效率前前后后又提高了一萬多倍,與最初的PHP程序相比,運算效率已經提高了大約200萬倍。 盡管如此,我還是不滿意,因為問題稍微復雜些,且要求的精度再高些,我的電腦還是要沒日沒夜轉好幾天,我希望程序運算速度能夠再有至少一個數量級的提升,在軟件上能改進的地方幾乎都改進了,只能在硬件上想辦法了。

我本以為,按照摩爾定律,CPU的運算速度每一年半要提升一倍,不怕大家笑話,我現在的電腦是2007年買的,已經過去七年了,最新的CPU速度應該提升二十多倍了,於是我上網查了一下,竟然發現最新款的電腦,CPU的主頻不過比我的多10%左右,這是怎么回事?再查才知道,原來CPU的摩爾定律到2008年左右就失效了,這么多年來CPU主頻都沒有大的變化,主要靠不斷增加CPU的數量(雙核、四核、八核.......)進一步提高電腦性能,但這種多核結構對於我要解決的問題,幫助似乎並不明顯。

於是我就想到比特幣文章中提到的GPU運算——這個從來沒覺得會與自己有關系的東西。

查了一些文章,大致了解到GPU之所以比CPU快得多,並不是GPU的處理器運算速度更快——其實目前最好的顯卡,處理器的主頻也不到CPU的一半——但是CPU只有一個處理器,而GPU的處理器少則幾十個,多則幾千個,一只手干活干得再快,也沒有成百上千只手一起干活干得快,就是這個道理。

GPU這個特點決定了並不是所有程序都適合用GPU來加速,只有你的問題能夠分解為若干能夠獨立執行的部分(即一部分程序的運算,並不依賴於另一部分運算的運行結果),才適合考慮用GPU來處理,這也是GPU編程的核心觀念:並行運算。

既然GPU是成百上千只手一起干活,那么GPU的價格為什么不是CPU的成百上千倍呢?關鍵就在於GPU的“手”與CPU的“手”相比是帶有明顯殘疾的,只有完成某些特定動作的時候效率高,完成其他動作效率就很低。具體表現在:

(1)所有的“手”(或者叫處理器、線程)完成相同動作時效率高,完成不同動作時效率低——這一條是顯卡編程最關鍵、最核心的部分,這決定了GPU雖然有幾千只手,但不可能像工廠工人那樣進行流水作業,你裝填,我打包,他裝箱,這對於GPU是行不通的。大家都一起打包,然后大家一起來裝箱,只有這樣的方式才適合讓GPU來處理。    

(2)如果各個並行的部分(即各個線程),需要共享大量數據,那么不適合用GPU進行處理。要注意,我說的是“不能共享大量數據”,這里並不是說GPU不適合處理大量數據,相反,由於GPU具有較大的顯存空間(比較差的顯卡也有2G顯存)和非常快的數據吞吐速度(專業術語叫帶寬),所以非常適合做大數據的處理。GPU編程的一個早期經典案例就是醫學圖像的處理,據說有個醫生發明了一種彩超快速診斷子宮肌瘤的方法,但是如果用CPU處理幾個T的彩超檢查數據的話,幾天都搞不定,后來改用GPU處理,幾十分鍾就解決了——所以處理大數據是GPU的強項。

但這是指各個線程獨立的讀取一部分專屬於自己的數據,那么處理的速度可以很高。如果大量的線程,要相互交錯的同時訪問大量數據那么運行效率就很低。打個比方:菜市場每一個攤位相當於一個要被訪問的數據,逛菜市場的人相當於不同的線程,那么大家雜亂無章的在市場里亂逛,運行效率就很低。如果大家排好隊進場,規定一個人只准面對一個攤位,那么運行效率就會很高。

(3)並行處理的線程數不能太少。如果你的程序只能分解為幾百個並行運算的部分,就不適合用GPU來處理——至少要有幾千個並行的線程才能勉強體現出GPU的優勢,如果你的程序撐死了也就分解為兩三千個並行的部分,那么還是建議你不要考慮用GPU加速了——舉個例子,我用GPU運行我的神經網絡(我的顯卡非常差,只有48個處理器),剛把程序運行通的時候,我安排了1024個線程進行測試,與我原來的CPU程序相比,速度只提高了20%左右,讓我大失所望。后來發發狠,把並行的線程數安排到8192個——速度竟然提高到了原來的八倍左右——這讓我欣喜若狂,這意味着如果我換更好的顯卡,比如有兩千多個處理器的顯卡,那么我的程序速度還有四五十倍的提升空間,這樣一來我的算法速度有望比在CPU的速度提高2-3個數量級,想想都讓人興奮。  

 需要說明一下,這個教程叫“菜鳥入門”,這里的“菜鳥”是指顯卡編程方面的菜鳥,而不是指編程菜鳥。要學顯卡編程,一定要對C/C++比較熟練,對指針的運用比較自如,才可能進行顯卡編程——也可以說距離顯卡編程就很近了,據說很久很久以前......顯卡編程是一件非常麻煩的大工程,后來一種叫CUDA的東西橫空出世——顯卡廠商NVIDIA推出的顯卡運算平台——顯卡編程就變得非常簡單了,只要在熟練C的前提下,學幾個簡單的語句就可以搞定。

由於我是在windows上進行顯卡編程的,我簡單說一下我我在windows上安裝CUDA遇到的一些問題(詳細安裝步驟請自行搜索相關文獻,我這里只提一下文獻中很少提及的需要注意的問題,以幫助各位少走彎路,至於使用Linux的同學,只能是自己查閱文獻慢慢摸索了)。

(一)需要先安裝Visual Studio(其他C/C++的SDK似乎都不行),有的文獻說可以用VC EXPRESS,但我安了VC EXPRESS,死活用不了,后來裝了全套Visual Studio 才搞定。

(二)安裝好Visual Studio之后,到NVIDIA官網下載CUDA安裝包,安裝時務必選擇“自定義安裝”,務必勾選全部安裝項目。

(三)CUDA安裝好后,可以搜索一個叫CUDA-Z的小軟件,這個軟件可以顯示你的顯卡的狀態。下載運行后,如果告訴你顯卡沒有運行,很可能是你的顯卡驅動太舊了——哪怕你是剛下載的最新的安裝包,也可能出這個問題——你需要升級顯卡驅動。另外我有個朋友遇到這樣的問題:顯卡沒有運行,后來發現他是遠程登陸,他到本地使用的時候,顯卡就正常了——我分析是遠程登陸后,顯卡就休眠了。

上面步驟完成后,就可以打開VS,新建一個CUDA工程,然后就可以開始第一個CUDA程序了:

 

  1. #include <cuda_runtime.h>
  2.  
  3. void main()
  4.  
  5. {printf("Hello world");
  6.  
  7. }

 

 http://blog.csdn.net/yfszzx/article/details/41654415

慢着,這個程序和C有什么區別?用到顯卡了嗎?

答:沒有區別,沒用顯卡。如果你非要用顯卡干點什么事情的話,可以改成這個樣子:

  1. #include <cuda_runtime.h>
  2. __global__ void test()
  3.  
  4. {int i=0;}
  5.  
  6. void main()
  7.  
  8. {test<<<1,1>>>();
  9.  
  10. printf("Hello world");
  11.  
  12. }

這樣,我們就用顯卡的一個線程,執行了一個int i=0語句。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM