多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 服務器 > 【CUDA并行編程之七】數組元素之和

【CUDA并行編程之七】數組元素之和

來源:程序員人生   發布時間:2015-01-31 10:19:05 閱讀次數:3805次

現在需要求得1個數組的所有元素之和,之前感覺似乎不太可能,由于每一個線程只處理1個元素,沒法將所有元素聯系起來,但是最近學習了1段代碼可以實現,同時也對shared memory有了進1步的理解。


1、C++串行實現

串行實現的方法非常之簡單,只要將所有元素順次相加就可以夠得到相應的結果,實際上我們重視的不是結果,而是運行的效力。那末代碼以下:

array_sum.cc:

#include<iostream> #include<stdio.h> #include "kmeans.h" using namespace std; const int cnt = 100000; int main() { int *a = new int[cnt]; for(int i=0;i<cnt;i++) { a[i] = i+1; } double t = wtime(); for(int i=0;i<cnt;i++) sum += a[i]; printf("computation elapsed %.8f ",wtime()-t); return 0; }

wtime.cu:

#include <sys/time.h> #include <stdio.h> #include <stdlib.h> double wtime(void) { double now_time; struct timeval etstart; struct timezone tzp; if (gettimeofday(&etstart, &tzp) == ⑴) perror("Error: calling gettimeofday() not successful. "); now_time = ((double)etstart.tv_sec) + /* in seconds */ ((double)etstart.tv_usec) / 1000000.0; /* in microseconds */ return now_time; }
運行結果:



2、CUDA并行實現

先上代碼然后再進行解釋:

#include <iostream> #include <stdio.h> #include "kmeans.h" using namespace std; const int count = 1000; void generate_data(int *arr) { for(int i=0;i<count;i++) { arr[i] = i+1; } } int nextPowerOfTwo(int n) { n--; n = n >> 1 | n; n = n >> 2 | n; n = n >> 4 | n; n = n >> 8 | n; n = n >> 16 | n; //n = n >> 32 | n; //For 64-bits int return ++n; } /* cnt : count cnt2 : next power of two of count */ __global__ static void compute_sum(int *array,int cnt , int cnt2) { extern __shared__ unsigned int sharedMem[]; sharedMem[threadIdx.x] = (threadIdx.x < cnt) ? array[threadIdx.x] : 0 ; __syncthreads(); //cnt2 "must" be a power of two! for( unsigned int s = cnt2/2 ; s > 0 ; s>>=1 ) { if( threadIdx.x < s ) { sharedMem[threadIdx.x] += sharedMem[threadIdx.x + s]; } __syncthreads(); } if(threadIdx.x == 0) { array[0] = sharedMem[0]; } } int main() { int *a = new int[count]; generate_data(a); int *deviceArray; cudaMalloc( &deviceArray,count*sizeof(int) ); cudaMemcpy( deviceArray,a,count*sizeof(int),cudaMemcpyHostToDevice ); int npt_count = nextPowerOfTwo(count);//next power of two of count //cout<<"npt_count = "<<npt_count<<endl; int blockSharedDataSize = npt_count * sizeof(int); double t = wtime(); for(int i=0;i<count;i++) { compute_sum<<<1,count,blockSharedDataSize>>>(deviceArray,count,npt_count); } printf("computation elapsed %.8f ",wtime()-t); int sum ; cudaMemcpy( &sum,deviceArray,sizeof(int),cudaMemcpyDeviceToHost ); cout<<"sum = "<<sum<<endl; return 0; }


主函數:
line58:
為數組a賦初值,維度為count。

line60~62:定義device變量并分配內存,將數組a的值拷貝到顯存上去。

line63:nextPowerOfTwo是非常精巧的1段代碼,它計算大于等于輸入參數n的第1個2的冪次數。至于為何這么做要到kernel函數里面才能明白。

line68:compute_sum中的"1"為block的數量,"count"為每一個block里面的線程數,"blockSharedDataSize"為同享內存的大小。

核函數compute_sum:

line35:定義shared memory變量。

line36:將threadIdx.x小于cnt的對應的sharedMem的內存區賦值為數組array中的值。

line39~47:這段代碼的功能就是將所有值求和以后放到了shareMem[0]這個位置上。這段代碼要好好體會1下,它把本來計算復雜度為O(n)的串行實現的時間效力通過并行到達了O(logn)。最后將結果保存到array[0]并拷貝回主存。

makefile:

cu: nvcc cuda_array_sum.cu wtime.cu ./a.out
結果:



3、效力對照

我們通過修改count的值并且加大循環次數來視察變量的效力的差別。

代碼修改:




運行時間對照:

count
串行(s)
并行(s)
1000
0.00627995
0.00345612
10000
0.29315591
0.06507015
100000
25.18921304
0.65188980
1000000
2507.66827798
5.61648989



哈哈,可見在數據量大的情況下效力還是相當不錯的。

Author:憶之獨秀

Email:leaguenew@qq.com

注明出處:http://blog.csdn.net/lavorange/article/details/43031419


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲视频一区二区 | 亚洲欧美综合在线观看 | 国产免费高清福利拍拍拍 | 玖玖中文| 最近最新在线中文字幕 | 97精品国产综合久久久久久欧美 | 一级毛片一级毛片一级毛片aa | 在线免费观看h视频 | 视频在线观看免费视频 | 国产一区二区三区在线 | 精品国产v无码大片在线观看 | 亚洲精品免费在线观看 | 性欧美18 | 亚洲成a人片在线播放观看国产 | 欧美久久久久欧美一区 | 色交视频 | 成人资源在线 | 日韩3区| 国产精品亚洲精品日韩动图 | 成人在线亚洲 | 国产精品96久久久久久久 | 国产区一区 | 顶级欧美色妇xxxxbbbb | 亚洲一级二级三级 | 亚洲春色在线视频 | 疯狂奶水freeseⅹ | www.欧美色 | 国产在线拍揄自揄视精品不卡 | 国产成人久久精品激情91 | 欧美成人全部免费观看1314色 | 亚洲欧洲精品国产二码 | 看毛片的网址 | 精品一区二区三区中文字幕 | 最近中文字幕无吗免费视频 | 色偷偷亚洲女人天堂观看欧 | 国产免费高清 | 日韩性生活视频 | 国产福利视频一区二区三区四区 | 日本一区二区视频 | 国产91精品福利在线观看 | 欧美久久久久久久久 |