同步

設備和主機之間的同步

//顯式同步,阻塞直到該語句前得所有kernel調用執行完畢
cudaError_t cudaDeviceSynchronize(void);

//隱式同步
cudaError_t cudaMemcpy(void* dst, const void* src, size_t count, cudaMemcpyKind kind);

線程塊內的同步

  • 同一線程塊內的同步方式有兩種:
      Barriers
      Memory Fences

    __device__ void __syncthreads();
    __device__ void __threadfence_block();
    
  • Weakly-Ordered Memory Model指的是gpu對內存的寫入操作未必是立即完成的,線程可能等到需要讀取該段內存時,纔將這之前的寫入操作完成
  • 當線程同步語句包含在執行分支中時,要確保同一線程束內的所有線程都執行相同的分支,否則程序可能僵死

    if(threadIdx.x % 2 == 0) {
        __syncthreads();
    }
    else {
        __syncthreads();
    }
    
  • 實際上,memory fence支持塊內同步,網格內同步,主機-設備,設備-設備同步。調用memory fence的線程會阻塞直到對應的線程集合中所有對全局內存,共享內存,頁鎖定內存,其他設備的全局內存的寫入都完成

    void __threadfence_block();         //塊同步
    void __threadfence();               //網格同步
    void __threadfence_system();        //系統同步
    

線程塊之間同步

  • cuda不直接支持塊間barrier,但由於同一stream中的多個kernel的執行是串行的,可以把需要塊間同步的kernel分割成多個kernel,每個分割點對應一個barrier
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章