@@ -30,57 +30,112 @@ namespace ptx = cuda::ptx;
3030 } \
3131 }
3232
33- __global__ __noinline__ void test_mbarrier_kernel () {
33+ __global__ __noinline__ void test_mbarrier_kernel (uint64_t *sink ) {
3434 // mbarrier object is 64bit in shared memory
3535 __shared__ uint64_t mbarrier;
3636 uint64_t state;
3737 int32_t count;
3838 // Initialize the mbarrier with PTX asm
3939 int block_size = blockDim .x * blockDim .y ;
4040 if (threadIdx .x == 0 && threadIdx .y == 0 ) {
41- asm (" mbarrier.init.shared::cta.b64 [%0], %1;" : : " l" (&mbarrier), " r" (block_size ) : " memory" );
41+ asm (" mbarrier.init.shared::cta.b64 [%0], %1;" : : " l" (&mbarrier), " r" (0x1234 ) : " memory" );
4242 }
4343 __syncthreads ();
4444
4545 // Expect on the mbarrier
4646#if __CUDA_ARCH__ >= 900
4747 int bytes_per_thread = 4 ;
48+ asm (" barrier.sync 0;" );
49+ // SYNCS.ARRIVE.TRANS64.RED.A0TR
4850 asm (" mbarrier.expect_tx.shared::cta.b64 [%0], %1;" : : " l" (&mbarrier), " r" (bytes_per_thread) : " memory" );
49- __syncthreads ( );
51+ asm ( " mbarrier.expect_tx.shared::cluster.b64 [%0], %1; " : : " l " (&mbarrier), " r " ( 2 *bytes_per_thread) : " memory " );
5052
5153 // Complete on the mbarrier
52- asm (" mbarrier.complete_tx.shared::cta.b64 [%0], %1;" : : " l" (&mbarrier), " r" (bytes_per_thread) : " memory" );
53- __syncthreads ();
54+ asm (" barrier.sync 1;" );
55+ // SYNCS.ARRIVE.TRANS64.RED.A0TX
56+ asm (" mbarrier.complete_tx.shared::cta.b64 [%0], %1;" : : " l" (&mbarrier), " r" (3 *bytes_per_thread) : " memory" );
5457
5558 // All threads in the block arrive on the mbarrier
56- asm (" mbarrier.arrive.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (1 ) : " memory" );
57- __syncthreads ();
59+ asm (" barrier.sync 2;" );
60+ // SYNCS.ARRIVE.TRANS64.RED.A1T0 (no count specified, return value is not used)
61+ asm (" mbarrier.arrive.b64 %0, [%1];" : " =l" (state) : " l" (&mbarrier) : " memory" );
62+ asm (" mbarrier.arrive.b64 _, [%0];" :: " l" (&mbarrier) : " memory" );
63+ // SYNCS.ARRIVE.TRANS64.A1T0 (return value is used)
64+ asm (" mbarrier.arrive.b64 %0, [%1];" : " =l" (state) : " l" (&mbarrier) : " memory" );
65+ *sink += state;
66+ // SYNCS.ARRIVE.TRANS64.RED.ART0 (return value state is not used)
67+ asm (" mbarrier.arrive.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (4 ) : " memory" );
68+ asm (" mbarrier.arrive.b64 _ , [%0], %1;" : : " l" (&mbarrier), " n" (4 ) : " memory" );
69+ // SYNCS.ARRIVE.TRANS64.ART0 (return value state is used)
70+ asm (" mbarrier.arrive.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (5 ) : " memory" );
71+ *sink += state;
72+
73+ // ARRIVE with no complete
74+ asm (" barrier.sync 3;" );
75+ // SYNCS.ARRIVE.TRANS64.RED.ART0
76+ asm (" mbarrier.arrive.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (5 ) : " memory" );
77+ // SYNCS.ARRIVE.TRANS64.TMASK.ART0 (return value is used)
78+ asm (" mbarrier.arrive.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (6 ) : " memory" );
79+ *sink += state;
5880
5981 // Arrive and expect on the mbarrier
60- asm (" mbarrier.arrive.expect_tx.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (2 ) : " memory" );
61- __syncthreads ();
82+ asm (" barrier.sync 4;" );
83+ // SYNCS.ARRIVE.TRANS64.RED (return value is not used)
84+ asm (" mbarrier.arrive.expect_tx.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (6 ) : " memory" );
85+ asm (" mbarrier.arrive.expect_tx.b64 _, [%0], %1;" :: " l" (&mbarrier), " n" (6 ) : " memory" );
86+ // SYNCS.ARRIVE.TRANS64 (return value is used)
87+ asm (" mbarrier.arrive.expect_tx.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (6 ) : " memory" );
88+ *sink += state;
6289
6390 // Arrive and drop
91+ asm (" barrier.sync 5;" );
92+ // SYNCS.ARRIVE.TRANS64.RED.OPTOUT.A1T0 (not using return value)
93+ asm (" mbarrier.arrive_drop.b64 %0, [%1];" : " =l" (state) : " l" (&mbarrier) : " memory" );
94+ asm (" mbarrier.arrive_drop.b64 _, [%0];" :: " l" (&mbarrier) : " memory" );
95+ // SYNCS.ARRIVE.TRANS64.OPTOUT.A1T0 (using return value)
96+ asm (" mbarrier.arrive_drop.b64 %0, [%1];" : " =l" (state) : " l" (&mbarrier) : " memory" );
97+ *sink += state;
98+
99+ // SYNCS.ARRIVE.TRANS64.RED.OPTOUT.ART0 (not using return value)
64100 asm (" mbarrier.arrive_drop.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (3 ) : " memory" );
65- __syncthreads ();
101+ asm (" mbarrier.arrive_drop.b64 _, [%0], %1;" :: " l" (&mbarrier), " n" (3 ) : " memory" );
102+ // SYNCS.ARRIVE.TRANS64.OPTOUT.ART0 (using return value)
103+ asm (" mbarrier.arrive_drop.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (3 ) : " memory" );
104+ *sink += state;
105+
106+ asm (" barrier.sync 6;" );
107+ // SYNCS.ARRIVE.TRANS64.RED.OPTOUT.ART0
108+ asm (" mbarrier.arrive_drop.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (3 ) : " memory" );
109+ asm (" mbarrier.arrive_drop.noComplete.b64 _, [%0], %1;" :: " l" (&mbarrier), " n" (3 ) : " memory" );
110+ // SYNCS.ARRIVE.TRANS64.TMASK.OPTOUT.ART0
111+ asm (" mbarrier.arrive_drop.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (3 ) : " memory" );
112+ *sink += state;
113+
66114#else
67115 // For sm_80
68116 // All threads in the block arrive on the mbarrier
117+ asm (" barrier.sync 5;" );
69118 asm (" mbarrier.arrive.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (1 ) : " memory" );
70- __syncthreads ();
71119
72- // Arrive and drop
120+ // Arrive and drop with no complete
121+ asm (" barrier.sync 6;" );
73122 asm (" mbarrier.arrive_drop.noComplete.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (3 ) : " memory" );
74- __syncthreads ();
75123#endif
76124
77125#if __CUDA_ARCH__ >= 900
78- // Arrive and drop
126+ // Arrive and drop expect tx
127+ asm (" barrier.sync 7;" );
128+ // SYNCS.ARRIVE.TRANS64.RED.OPTOUT
79129 asm (" mbarrier.arrive_drop.expect_tx.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (4 ) : " memory" );
80- __syncthreads ();
130+ asm (" mbarrier.arrive_drop.expect_tx.b64 _, [%0], %1;" :: " l" (&mbarrier), " n" (5 ) : " memory" );
131+ // SYNCS.ARRIVE.TRANS64.OPTOUT RA, [URB], RC; RC is the transaction count
132+ asm (" mbarrier.arrive_drop.expect_tx.b64 %0, [%1], %2;" : " =l" (state) : " l" (&mbarrier), " n" (6 ) : " memory" );
133+ *sink += state;
81134#endif
82135
83136 // Get pending count
137+ asm (" barrier.sync 8;" );
138+ // This is just a list of arithematic operations on the opaque state variable
84139 asm (" mbarrier.pending_count.b64 %0, %1;" : " =r" (count) : " l" (state) : " memory" );
85140 // Prevent optimizing away
86141 if (threadIdx .x == 0 && threadIdx .y == 0 ) {
@@ -89,31 +144,90 @@ __global__ __noinline__ void test_mbarrier_kernel() {
89144 __syncthreads ();
90145
91146 // cp async barrier arrive
147+ asm (" barrier.sync 9;" );
148+ // SYNCS.ARRIVE.TRANS64.RED.A0T1 RZ, [URB], RZ
149+ // ARRIVES.LDGSTSBAR.64.TRANSCNT [URB]
92150 asm (" cp.async.mbarrier.arrive.shared::cta.b64 [%0];" : : " l" (&mbarrier) : " memory" );
93- __syncthreads ();
151+ asm (" barrier.sync 10;" );
152+ // ARRIVES.LDGSTSBAR.64.ARVCNT [URB]
94153 asm (" cp.async.mbarrier.arrive.noinc.shared::cta.b64 [%0];" : : " l" (&mbarrier) : " memory" );
95- __syncthreads ();
96154
97155 // Wait on the mbarrier
98156#if __CUDA_ARCH__ >= 900
157+ asm (" barrier.sync 11;" );
158+ // SYNCS.PHASECHK.TRANS64 PT, [UR4], RZ
99159 asm (" \n\t "
100160 " .reg .pred complete;\n\t "
101161 " mbarrier.test_wait.parity.b64 complete, [%0], %1;"
102162 : : " l" (&mbarrier), " n" (0 ) : " memory"
103163 );
104- __syncthreads ();
164+ asm (" barrier.sync 12;" );
165+ // SYNCS.PHASECHK.TRANS64 PT, [UR4], R0
166+ asm (" \n\t "
167+ " mbarrier.test_wait.parity.b64 complete, [%0], %1;"
168+ : : " l" (&mbarrier), " n" (1 ) : " memory"
169+ );
170+ asm (" barrier.sync 0;" );
171+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [UR4], RZ
105172 asm (" \n\t "
106173 " mbarrier.try_wait.parity.b64 complete, [%0], %1;"
107174 : : " l" (&mbarrier), " n" (0 ) : " memory"
108175 );
176+ asm (" barrier.sync 1;" );
177+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [UR4], R0
178+ asm (" \n\t "
179+ " mbarrier.try_wait.parity.b64 complete, [%0], %1;"
180+ : : " l" (&mbarrier), " n" (1 ) : " memory"
181+ );
182+ asm (" barrier.sync 2;" );
183+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [R4+URZ], RZ
184+ // @!PT NANOSLEEP.SYNCS 0x1234
185+ asm (" \n\t "
186+ " mbarrier.try_wait.parity.b64 complete, [%0], %1, %2;"
187+ : : " l" (&mbarrier), " n" (0 ), " n" (0x1234 ) : " memory"
188+ );
189+ asm (" barrier.sync 3;" );
190+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [R5+URZ], R3
191+ // @!PT NANOSLEEP.SYNCS 0x4321
192+ // @!PT SYNCS.PHASECHK.TRANS64 PT, [R5+URZ], R3 ;
193+ asm (" \n\t "
194+ " mbarrier.try_wait.parity.b64 complete, [%0], %1, %2;"
195+ : : " l" (&mbarrier), " n" (1 ), " n" (0x4321 ) : " memory"
196+ );
109197 __syncthreads ();
198+
199+ state = 0 ;
200+ asm (" barrier.sync 4;" );
201+ // SYNCS.PHASECHK.TRANS64 PT, [UR4], RZ
202+ asm (" \n\t "
203+ " .reg .pred complete2;\n\t "
204+ " mbarrier.test_wait.b64 complete2, [%0], %1;"
205+ : : " l" (&mbarrier), " l" (state) : " memory"
206+ );
207+ asm (" barrier.sync 5;" );
208+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [UR4], RZ
209+ asm (" \n\t "
210+ " mbarrier.try_wait.b64 complete2, [%0], %1;"
211+ : : " l" (&mbarrier), " l" (state) : " memory"
212+ );
213+ asm (" barrier.sync 6;" );
214+ // SYNCS.PHASECHK.TRANS64.TRYWAIT PT, [R6+URZ], RZ
215+ // @!PT NANOSLEEP.SYNCS 0x1234
216+ // @!PT SYNCS.PHASECHK.TRANS64 PT, [R6+URZ], RZ ;
217+ asm (" \n\t "
218+ " mbarrier.try_wait.b64 complete2, [%0], %1, %2;"
219+ : : " l" (&mbarrier), " l" (state), " n" (0x1234 ) : " memory"
220+ );
110221#endif
111222}
112223
113224int main (int argc, char *argv[]) {
114- CUDA_SAFECALL ((test_mbarrier_kernel<<<1 , 1 >>> ()));
115- CUDA_SAFECALL (cudaDeviceSynchronize ());
225+ printf (" This is a test program mean to compare the mbarrier PTX and SASS mapping, it is not tested at all for functionality/run to finished\n " );
226+ // uint64_t *sink;
227+ // cudaMalloc(&sink, sizeof(uint64_t));
228+ // CUDA_SAFECALL((test_mbarrier_kernel<<<1, 1>>>(sink)));
229+ // CUDA_SAFECALL(cudaDeviceSynchronize());
116230
117- printf (" Mbarrier test completed\n " );
231+ // printf("Mbarrier test completed\n");
118232 return 0 ;
119233}
0 commit comments