zoukankan      html  css  js  c++  java
  • cuda基础---cuda通信机制

    1:同步函数

    1)__syncthreads()

      实现线程块中的线程同步----保证线程块中所有线程执行到同一位置;

      只有当整个线程块都走向相同分支时,才能在条件语句中使用__syncthreads)(;

      一个warp内的线程不用同步;

      __syncthreads()调用花费时间周期,应尽量避免/节约使用。

    2)memory fence 函数

      保证数据通信的可靠性,并不要求所有线程都运行到同一位置;

      多个线程间可以正确的操作共享数据,实现grid/block内的线程间通信。

    (1)__threadfence()

      该函数调用后,该线程在此语句前对全局存储器或共享存储器的访问已经全部完成,且结果对grid内所有线程可见。

    (2)__threadfence_block()

      该函数调用后,该线程在此语句前对全局存储器或共享存储器的访问已经全部完成,且结果对block内所有线程可见。

    (3)实例---N个元素求和

     1 __device__ unsigned int count = 0;
     2 __shared__ bool isLastBlockDone;
     3 
     4 //每个block首先计算出数组的一个子序列的和,再将结果存储到全局内存
     5 //所有block完成后,由最后一个块完成求和操作
     6 
     7 __global__ void sum(const float* array,unsigned int N,float* result)
     8 {
     9 //每个block对输入数组的一个subset求和
    10 float partialSum = calcultePartialSum(array,N);
    11 if(threadIdx.x == 0)
    12 {
    13 //0号线程存储局部和partialSum并负责写回全局存储器
    14 result[blockIdx.x] = partialSum;
    15 //线程0要保证它的结果对所有其他的线程可见
    16 __threadfence();
    17 //每个block的0号线程负责计算结束后做一次标记,count++
    18 unsigned int value = atomicInc(&count,gridDim.x);
    19 //每个block的0号线程来判断该块是否是最后一个计算结束的快
    20 isLastBlckDone = (value == gridDim.x-1);
    21 }
    22 //做一次同步,保证每个线程读到正确的isLastBlockDone值
    23 __syncthreads();
    24 
    25 if(isLastBlockDone)
    26 {
    27 //最后的那个block负责局部和的球和
    28 float totalSum = calculateTotalSum(result);
    29 if(threadIdx.x == 0)
    30 {//last block的线程0存储急速那和并将其协会全局存储器,count 置0来保证下一个kernel的正常计数
    31 result[0] = totalSum;
    32 count = 0;
    33 }
    34 }
    35 }

    3)kernel间通信

      通过global memory实现--pinned memory

    4)GPU与CPU线程同步

      A:主机端代码使用cudaThreadSynchronize()----确定所有设备端线程均已运行结束

    2:volatile关键字

      存在于全局变量或共享存储器中的变量通过此关键字声明为敏感变量。每次对该变量的引用都会被编译成一次真实的内存读指令。

    3:ATOM操作

      当多个线程同时访问全局或共享存储器的同一位置时,保证每个线程能够实现对共享可写数据的互斥操作--在一个操作完成之前,其他任何线程都无法访问此地址。

     1 __global__ void testAtom(int* g_odata)
     2 {
     3 const unsigned int tid = blockDim.x*blockIdx.x+threadIdx.x;
     4 
     5 //算术原子操作
     6 atomicAdd(&g_odata[0],10);
     7 atomicMax(&g_odata[0],tid);
     8 atomicInc((unsigned int*)&g_odata[0],17);
     9 atomicCAS(&g_odata[0],tid-1,tid);
    10 
    11 //位原子操作
    12 atomicAnd(&g_odata[8],2*tid+7);
    13 atomicOr(&g_odata[8],1<<tid);
    14 atomicXor(&g_odata[8],tid);        
    15 }

    A:图像亮度直方图统计

    4:VOTE操作

      由下面两个函数实现此指令

    A:int __all(int predicate);

      一个warp中所有的threads的判断表达式结果为真则返回1;否则返回0

    B:int __any(int predicate);

      一个warp中只要存在thread的判断表达式结果为真,则返回1,否则返回0.

  • 相关阅读:
    HBase Java API 创建表时一直卡住
    HBase Shell常用的命令
    Three.js中自定义控制几何体的点和面的属性
    Three.js中使用材质覆盖属性
    2021.7.28 发布 gcc-11.2
    解决a 标签在ie8下面不下载问题
    sourceTree拉取代码报错:remote: HTTP Basic: Access denied
    javaScript网页版调用百度地图API (支持HTTPS,兼容IE6+)
    js 时间戳与时间的相互转换
    HTB-Pathfinder
  • 原文地址:https://www.cnblogs.com/pengtangtang/p/13060003.html
Copyright © 2011-2022 走看看