国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

CUDA線程協(xié)作之共享存儲(chǔ)器“__shared__”&&“__syncthreads()”

2019-11-11 07:55:04
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
在GPU并行編程中,一般情況下,各個(gè)處理器都需要了解其他處理器的執(zhí)行狀態(tài),在各個(gè)并行副本之間進(jìn)行通信和協(xié)作,這涉及到不同線程間的通信機(jī)制和并行執(zhí)行線程的同步機(jī)制。

共享內(nèi)存“__share__”

CUDA中的線程協(xié)作主要是通過(guò)共享內(nèi)存實(shí)現(xiàn)的。使用關(guān)鍵字“__share__”聲明共享變量,將使這個(gè)變量駐留在共享內(nèi)存中,該變量具有以下特征:位于線程塊的共享存儲(chǔ)器空間中與線程塊具有相同的生命周期僅可通過(guò)塊內(nèi)的所有線程訪問(wèn)對(duì)于GPU上啟動(dòng)的每個(gè)線程塊,CUDA C編譯器都將創(chuàng)建該變量的一個(gè)副本。 線程塊中的每個(gè)線程都共享這塊內(nèi)存,但線程卻無(wú)法看到也不能修改其他線程塊的變量副本。 這就使得一個(gè)線程塊中的多個(gè)線程能夠在計(jì)算上進(jìn)行通信和協(xié)作。而且,共享內(nèi)存緩沖區(qū)駐留在物理GPU上,在訪問(wèn)共享內(nèi)存時(shí)的延遲要遠(yuǎn)遠(yuǎn)低于訪問(wèn)普通緩沖區(qū)的延遲,使得共享內(nèi)存的訪問(wèn)非常高效。

線程同步機(jī)制“__syncthreads()”

關(guān)鍵字“__share__”只是聲明了共享變量,位于同一個(gè)線程塊中的不同線程都可以訪問(wèn)該變量,如果沒(méi)有同步機(jī)制,將會(huì)發(fā)生競(jìng)態(tài)條件 (Race Condition),導(dǎo)致錯(cuò)誤的運(yùn)行結(jié)果。CUDA確保同步的方法是調(diào)用“__syncthreads()”。__syncthreads()將確保線程塊中的每個(gè)線程都執(zhí)行完 __syncthreads()前面的語(yǔ)句后,才會(huì)執(zhí)行下一條語(yǔ)句。以下是CUDA和OpenCV的應(yīng)用中,繪制一幅圖像,Grid的尺寸大小是60*60,Block的尺寸大小是10*10,在各個(gè)線程塊內(nèi)聲明了一個(gè)共享變量sharedMem:
#include "cuda_runtime.h"    #include <highgui.hpp>    using namespace cv;#define DIM 600   //圖像長(zhǎng)寬#define PI 3.1415926535897932f  __global__ void kernel(unsigned char *ptr){	// map from blockIdx to pixel position    	int x = threadIdx.x + blockIdx.x * blockDim.x;	int y = threadIdx.y + blockIdx.y * blockDim.y;	int offset = x + y * blockDim.x * gridDim.x;	__shared__  float sharedMem[16][16];	const float period = 128.0f;	sharedMem[threadIdx.x][threadIdx.y] =		255 * (sinf(x*2.0f*PI / period) + 1.0f) *		(sinf(y*2.0f*PI / period) + 1.0f) / 4.0f;	__syncthreads();	ptr[offset * 3 + 0] = 0;	ptr[offset * 3 + 1] = sharedMem[15 - threadIdx.x][15 - threadIdx.y];	ptr[offset * 3 + 2] = 0;}// globals needed by the update routine    struct DataBlock{	unsigned char   *dev_bitmap;};int main(void){	DataBlock   data;	cudaError_t error;	Mat image = Mat(DIM, DIM, CV_8UC3, Scalar::all(0));	data.dev_bitmap = image.data;	unsigned char    *dev_bitmap;	error = cudaMalloc((void**)&dev_bitmap, 3 * image.cols*image.rows);	data.dev_bitmap = dev_bitmap;	dim3    grid(DIM / 10, DIM / 10);	dim3   block(10, 10);	//DIM*DIM個(gè)線程塊  	kernel << <grid, block >> > (dev_bitmap);	error = cudaMemcpy(image.data, dev_bitmap,		3 * image.cols*image.rows,		cudaMemcpyDeviceToHost);	error = cudaFree(dev_bitmap);	imshow("__share__ and __syncthreads()", image);	waitKey();}如果線程間不加入__syncthreads()同步機(jī)制,同一線程塊內(nèi)不同線程訪問(wèn)sharedMem,獲取的結(jié)果可能是不一樣的,生成的圖像如下,有散亂的雜點(diǎn):加入__syncthreads()同步機(jī)制,保證了同一線程塊中不同的線程都執(zhí)行完成__syncthreads()這個(gè)集合點(diǎn)之前的部分之后,才繼續(xù)往下執(zhí)行,所以不同的線程訪問(wèn)sharedMem獲取的結(jié)果是一致的,圖像無(wú)雜散點(diǎn),是一個(gè)規(guī)律的排布:
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 闽侯县| 澜沧| 都昌县| 鄢陵县| 额尔古纳市| 嵩明县| 荣成市| 杭锦旗| 鄄城县| 怀集县| 盐池县| 汉阴县| 西林县| 永川市| 格尔木市| 双城市| 宝应县| 正镶白旗| 通化市| 鄂州市| 灵台县| 赣州市| 宜宾县| 武乡县| 寿宁县| 永和县| 日喀则市| 罗田县| 德州市| 康平县| 眉山市| 周至县| 星子县| 肇源县| 双辽市| 茂名市| 延川县| 庆城县| 资中县| 文山县| 佛冈县|