cuda::barrier / async copies#
cuda::barrier / async copies (sim only) The sim copies synchronously and has no memory pipeline, so an async copy is a plain memcpy and a barrier is the block barrier. This models the RESULT of the <cuda/barrier> + cooperative_groups::memcpy_async idiom, not its latency hiding.
Defined in code/simulator.h.
This page documents 7 symbols: 1 enums, 6 functions.
Enums#
Signature |
Description |
Availability |
Location |
Example |
|---|---|---|---|---|
|
sim only |
simulator.h:3593 |
Functions#
Signature |
Description |
Availability |
Location |
Example |
|---|---|---|---|---|
|
sim only |
simulator.h:3598 |
||
|
sim only |
simulator.h:3601 |
||
|
sim only |
simulator.h:3600 |
||
|
sim only |
simulator.h:3603 |
||
|
sim only |
simulator.h:3604 |
||
|
sim only |
simulator.h:3599 |
Examples#
Code from the repository’s example corpus (code\*.cu); the highlighted line is the call site. These blocks are what the View links above open.
arrive (test_web_cs_awbarrier.cu:72)
62 SHARED_EXTERN(double, tmp); // [SIM] was: extern __shared__ double tmp[];
63
64#pragma unroll
65 for (int offset = tile32.size() / 2; offset > 0; offset /= 2) {
66 threadSum += tile32.shfl_down(threadSum, offset);
67 }
68 if (tile32.thread_rank() == 0) {
69 tmp[tile32.meta_group_rank()] = threadSum;
70 }
71
72 auto token = barrier.arrive();
73
74 barrier.wait(std::move(token));
75
76 // The warp 0 will perform last round of reduction
77 if (tile32.meta_group_rank() == 0) {
78 double beta = tile32.thread_rank() < tile32.meta_group_size()
79 ? tmp[tile32.thread_rank()]
80 : 0.0;
81
82#pragma unroll
83 for (int offset = tile32.size() / 2; offset > 0; offset /= 2) {
arrive_and_wait (test_web_cs_globaltoshmem.cu:123)
113 float4* const A4s = reinterpret_cast<float4*>(&As[threadIdx.y][t4x]);
114 float4* const B4s = reinterpret_cast<float4*>(&Bs[threadIdx.y][t4x]);
115 const float4* const A4 = reinterpret_cast<const float4*>(&A[a + wA * threadIdx.y + t4x]);
116 const float4* const B4 = reinterpret_cast<const float4*>(&B[a + wA * threadIdx.y + t4x]);
117
118 cuda::memcpy_async(A4s, A4, sizeof(float4), bar);
119 cuda::memcpy_async(B4s, B4, sizeof(float4), bar);
120 }
121
122 // Synchronize to make sure the matrices are loaded
123 bar.arrive_and_wait();
124
125#pragma unroll
126 for (int k = 0; k < BLOCK_SIZE; ++k) {
127 Csub += As[threadIdx.y][k] * Bs[k][threadIdx.x];
128 }
129
130 // Synchronize before the next iteration overwrites the tiles
131 bar.arrive_and_wait();
132 }
133
134 int c = wB * BLOCK_SIZE * blockIdx.y + BLOCK_SIZE * blockIdx.x;
init (test_web_cs_awbarrier.cu:108)
98 double* partialResults, int size) {
99#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 700
100 cg::thread_block cta = cg::this_thread_block();
101 cg::grid_group grid = cg::this_grid();
102
103 cg::thread_block_tile<32> tile32 = cg::tiled_partition<32>(cta);
104
105 __shared__ cuda::barrier<cuda::thread_scope_block> barrier;
106
107 if (threadIdx.x == 0) {
108 init(&barrier, blockDim.x);
109 }
110
111 cg::sync(cta);
112
113 double threadSum = 0.0;
114 for (int i = grid.thread_rank(); i < size; i += grid.size()) {
115 threadSum += (double)(vecA[i] * vecB[i]);
116 }
117
118 // Each thread block performs reduction of partial dotProducts and writes to
119 // global mem.
memcpy_async (test_web_cs_globaltoshmem.cu:118)
108 const int t4x = threadIdx.x * 4;
109
110 for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep) {
111 // Now, one fourth of the threads load four elements of each matrix
112 if (t4x < BLOCK_SIZE) {
113 float4* const A4s = reinterpret_cast<float4*>(&As[threadIdx.y][t4x]);
114 float4* const B4s = reinterpret_cast<float4*>(&Bs[threadIdx.y][t4x]);
115 const float4* const A4 = reinterpret_cast<const float4*>(&A[a + wA * threadIdx.y + t4x]);
116 const float4* const B4 = reinterpret_cast<const float4*>(&B[a + wA * threadIdx.y + t4x]);
117
118 cuda::memcpy_async(A4s, A4, sizeof(float4), bar);
119 cuda::memcpy_async(B4s, B4, sizeof(float4), bar);
120 }
121
122 // Synchronize to make sure the matrices are loaded
123 bar.arrive_and_wait();
124
125#pragma unroll
126 for (int k = 0; k < BLOCK_SIZE; ++k) {
127 Csub += As[threadIdx.y][k] * Bs[k][threadIdx.x];
128 }
wait (test_web_cs_awbarrier.cu:74)
64#pragma unroll
65 for (int offset = tile32.size() / 2; offset > 0; offset /= 2) {
66 threadSum += tile32.shfl_down(threadSum, offset);
67 }
68 if (tile32.thread_rank() == 0) {
69 tmp[tile32.meta_group_rank()] = threadSum;
70 }
71
72 auto token = barrier.arrive();
73
74 barrier.wait(std::move(token));
75
76 // The warp 0 will perform last round of reduction
77 if (tile32.meta_group_rank() == 0) {
78 double beta = tile32.thread_rank() < tile32.meta_group_size()
79 ? tmp[tile32.thread_rank()]
80 : 0.0;
81
82#pragma unroll
83 for (int offset = tile32.size() / 2; offset > 0; offset /= 2) {
84 beta += tile32.shfl_down(beta, offset);
85 }