统一寻址
大家好!我是CSDN?CUDA版塊新任版主!希望能夠盡自己的力量幫助大家解決有關CUDA編程的問題,并且會定期發布一些問題同大家一起討論,共同學習,共同進步!大家有問題可以發帖留言也可以發郵件到我的郵箱sparrow915791868@163.com。
????在大家的共同努力下,祝愿CSDN的CUDA版塊能夠越辦越好!
????下面進入此次討論的主題!
———————————————分割線————————————————————
????大家知道,Nvidia公司發布的CUDA6開發包擁有一個新特性,就是“統一內存尋址”,那究竟統一內存尋址有什么特殊的地方呢?我們編寫CUDA代碼跟以前有什么區別呢?現在擁有的GPU架構能夠很好的支持嗎?我們帶著這些問題開始我們的話題。
從名字上看,統一內存尋址就是將CPU端的內存同GPU顯存統一起來,使得程序猿在編寫代碼的時候不用明顯的使用諸如cudaMalloc或者cudaMemcpy等操作顯存的指令,而能夠在Kernel函數中直接使用定義的變量。
????例子如下:
原始代碼(CUDA6.0文檔)
C/C++ code?
統一尋址的代碼:
C/C++ code?
????從上面不同的代碼可以看出,統一尋址后的代碼更簡潔,使用了函數cudaMallocManaged()開辟一塊存儲空間,無論是在Kernel函數中還是main函數中,都可以使用這塊內存,達到了統一尋址的目的。
????這里有一個需要注意的地方就是main函數在調用Kernel函數之后,使用了一個同步函數。仔細思考后就會有所領悟——既然這塊存儲空間既可以被Kernel函數訪問,也可以被main函數訪問,為了解決訪問沖突的問題,因此使用了同步函數,使得在Kernel改變變量的值后,main函數才能使用該變量。
????上面只是簡單的舉了個例子,但已經把統一尋址的問題描述的很清楚:
????1.?開辟空間所使用的新函數;
????2.?變量訪問同步。
????在CUDA6.0的文檔中更加仔細的描述了相關的問題,包括流和多GPU條件下使用統一尋址的問題等,其主要針對的還是變量訪問同步,大家有興趣可以參看文檔。
????同AMD的APU不同,即使是Kepler架構的GPU,也不是真正意義上從硬件手段實現“統一內存尋址”,只是從軟件上解決的一種方式,Nvidia公司的新一代GPU產品——Maxwell架構,才真正是從硬件層面實現這一特性。而速度,還有待測試與研究~~
??既然“統一內存尋址”是GPU產品所前進的一個方向,勢必會改變我們的編程方式,因此,這一話題還是有重大的意義的,希望大家熱烈討論,在討論中真正掌握這一技術!
??謝謝大家~~!
????在大家的共同努力下,祝愿CSDN的CUDA版塊能夠越辦越好!
????下面進入此次討論的主題!
———————————————分割線————————————————————
????大家知道,Nvidia公司發布的CUDA6開發包擁有一個新特性,就是“統一內存尋址”,那究竟統一內存尋址有什么特殊的地方呢?我們編寫CUDA代碼跟以前有什么區別呢?現在擁有的GPU架構能夠很好的支持嗎?我們帶著這些問題開始我們的話題。
從名字上看,統一內存尋址就是將CPU端的內存同GPU顯存統一起來,使得程序猿在編寫代碼的時候不用明顯的使用諸如cudaMalloc或者cudaMemcpy等操作顯存的指令,而能夠在Kernel函數中直接使用定義的變量。
????例子如下:
原始代碼(CUDA6.0文檔)
C/C++ code?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | __global__?void?AplusB(int?*ret,?int?a,?int?b) { ??ret[threadIdx.x]?=?a?+?b?+?threadIdx.x; } int?main() { ??int?*ret; ??//************************************** ??cudaMalloc(&ret,?1000?*?sizeof(int)); ??AplusB<<<1,?1000>>>(ret,?10,?100); ??//************************************** ??int?*host_ret?=?(int?*)malloc(1000?*?sizeof(int)); ??cudaMemcpy(host_ret,?ret,?1000?*?sizeof(int),?cudaMemcpyDefault); ??for(int?i?=?0;?i?<?1000;?i++) ????printf("%d:?A?+?B?=?%d\n",?i,?host_ret[i]); ??free(host_ret); ??cudaFree(ret); ??return?0; } |
統一尋址的代碼:
C/C++ code?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | __global__?void?AplusB(int?*ret,?int?a,?int?b) { ??ret[threadIdx.x]?=?a?+?b?+?threadIdx.x; } int?main() { ??int?*ret; ??//*********************************************** ??cudaMallocManaged(&ret,?1000?*?sizeof(int)); ??AplusB<<<1,?1000>>>(ret,?10,?100); ??//*********************************************** ??cudaDeviceSynchronize(); ??for(int?i?=?0;?i?<?1000;?i++) ????printf("%d:?A?+?B?=?%d\n",?i,?ret[i]); ??cudaFree(ret); ??return?0; } |
????從上面不同的代碼可以看出,統一尋址后的代碼更簡潔,使用了函數cudaMallocManaged()開辟一塊存儲空間,無論是在Kernel函數中還是main函數中,都可以使用這塊內存,達到了統一尋址的目的。
????這里有一個需要注意的地方就是main函數在調用Kernel函數之后,使用了一個同步函數。仔細思考后就會有所領悟——既然這塊存儲空間既可以被Kernel函數訪問,也可以被main函數訪問,為了解決訪問沖突的問題,因此使用了同步函數,使得在Kernel改變變量的值后,main函數才能使用該變量。
????上面只是簡單的舉了個例子,但已經把統一尋址的問題描述的很清楚:
????1.?開辟空間所使用的新函數;
????2.?變量訪問同步。
????在CUDA6.0的文檔中更加仔細的描述了相關的問題,包括流和多GPU條件下使用統一尋址的問題等,其主要針對的還是變量訪問同步,大家有興趣可以參看文檔。
????同AMD的APU不同,即使是Kepler架構的GPU,也不是真正意義上從硬件手段實現“統一內存尋址”,只是從軟件上解決的一種方式,Nvidia公司的新一代GPU產品——Maxwell架構,才真正是從硬件層面實現這一特性。而速度,還有待測試與研究~~
??既然“統一內存尋址”是GPU產品所前進的一個方向,勢必會改變我們的編程方式,因此,這一話題還是有重大的意義的,希望大家熱烈討論,在討論中真正掌握這一技術!
??謝謝大家~~!
總結
- 上一篇: CUDA内存类型memory
- 下一篇: java声明公共构造函数_确保控制器具有