cuda实战阅读笔记:共享内存、常量内存、事件时间

共享内存变量

__shared__ type var;

所有线程都能对var进行操作,例如一个数组,每个线程写入var中的一项。
为保证所有线程均完成对var的读写后再对var进行操作,应使用 __syncthreads() 进行同步。

使用__syncthreads()应注意,线程代码不能让线程无法结束,导致__syncthreads永远得不到同步.

常量内存变量

__constant__ type var;

得益于GPU中巨量的线程,GPU的数据吞吐量不再受限于计算速度,而是带宽。GPU提供了常量内存,当线程们需要使用同一个常量时,将常量存放在常量内存中会减少带宽使用,提高访问速度。

常量内存大小查询方式,单位bytes。

cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, 0);
cout << prop.totalConstMem << endl;

将数据拷贝至常量内存

int arr[10000];
__constant__ int *const_arr;    
cudaMemcpyToSymbol(const_arr, arr, sizeof(int) * 10000);

为什么常量内存能提高性能呢?
首先要知道线程束的概念,一个线程束包含32个线程,32个线程同时执行代码的同一行。

当读取常量内存时,线程会广播到半线程束,即16个线程。若16个线程都需要读取同一个常量,则不用额外地访问常量内存,减少了15/16的内存流量。
当其他半线程束需要访问同一个常量时,会命中缓存,再次减少了内存流量。

但是,如果半线程束中的线程需要访问多个不同的常量,它们在访问常量内存时会排队,反而不如全局内存的访问效率。

用事件记录时间

cudaEvent_t event

创建事件,记录事件,计算事件之间的时间

    cudaEvent_t start, stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    cudaEventRecord(start);
    fun<<<16, 16 * 16>>>(); //long time
    cudaEventRecord(stop);
    cudaEventSynchronize(stop);
    float time;
    cudaEventElapsedTime(&time, start, stop);
    cout << time;

你可能感兴趣的:(GPU,GPU,cuda)