Skip to content

Commit 81ebee0

Browse files
committed
Added coalescing throughput test with offset and stride tests
1 parent 059d099 commit 81ebee0

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <stdio.h>
2+
#include <assert.h>
3+
4+
// Convenience function for checking CUDA runtime API results
5+
// can be wrapped around any runtime API call. No-op in release builds.
6+
inline
7+
cudaError_t checkCuda(cudaError_t result)
8+
{
9+
#if defined(DEBUG) || defined(_DEBUG)
10+
if (result != cudaSuccess) {
11+
fprintf(stderr, "CUDA Runtime Error: %s\n", cudaGetErrorString(result));
12+
assert(result == cudaSuccess);
13+
}
14+
#endif
15+
return result;
16+
}
17+
18+
template <typename T>
19+
__global__ void offset(T* a, int s)
20+
{
21+
int i = blockDim.x * blockIdx.x + threadIdx.x + s;
22+
a[i] = a[i] + 1;
23+
}
24+
25+
template <typename T>
26+
__global__ void stride(T* a, int s)
27+
{
28+
int i = (blockDim.x * blockIdx.x + threadIdx.x) * s;
29+
a[i] = a[i] + 1;
30+
}
31+
32+
template <typename T>
33+
void runTest(int deviceId, int nMB)
34+
{
35+
int blockSize = 256;
36+
float ms;
37+
38+
T *d_a;
39+
cudaEvent_t startEvent, stopEvent;
40+
41+
int n = nMB*1024*1024/sizeof(T);
42+
43+
// NB: d_a(33*nMB) for stride case
44+
checkCuda( cudaMalloc(&d_a, n * 33 * sizeof(T)) );
45+
46+
checkCuda( cudaEventCreate(&startEvent) );
47+
checkCuda( cudaEventCreate(&stopEvent) );
48+
49+
printf("Offset, Bandwidth (GB/s):\n");
50+
51+
offset<<<n/blockSize, blockSize>>>(d_a, 0); // warm up
52+
53+
for (int i = 0; i <= 32; i++) {
54+
checkCuda( cudaMemset(d_a, 0.0, n * sizeof(T)) );
55+
56+
checkCuda( cudaEventRecord(startEvent,0) );
57+
offset<<<n/blockSize, blockSize>>>(d_a, i);
58+
checkCuda( cudaEventRecord(stopEvent,0) );
59+
checkCuda( cudaEventSynchronize(stopEvent) );
60+
61+
checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
62+
printf("%d, %f\n", i, 2*nMB/ms);
63+
}
64+
65+
printf("\n");
66+
printf("Stride, Bandwidth (GB/s):\n");
67+
68+
stride<<<n/blockSize, blockSize>>>(d_a, 1); // warm up
69+
for (int i = 1; i <= 32; i++) {
70+
checkCuda( cudaMemset(d_a, 0.0, n * sizeof(T)) );
71+
72+
checkCuda( cudaEventRecord(startEvent,0) );
73+
stride<<<n/blockSize, blockSize>>>(d_a, i);
74+
checkCuda( cudaEventRecord(stopEvent,0) );
75+
checkCuda( cudaEventSynchronize(stopEvent) );
76+
77+
checkCuda( cudaEventElapsedTime(&ms, startEvent, stopEvent) );
78+
printf("%d, %f\n", i, 2*nMB/ms);
79+
}
80+
81+
checkCuda( cudaEventDestroy(startEvent) );
82+
checkCuda( cudaEventDestroy(stopEvent) );
83+
cudaFree(d_a);
84+
}
85+
86+
int main(int argc, char **argv)
87+
{
88+
int nMB = 4;
89+
int deviceId = 0;
90+
bool bFp64 = false;
91+
92+
for (int i = 1; i < argc; i++) {
93+
if (!strncmp(argv[i], "dev=", 4))
94+
deviceId = atoi((char*)(&argv[i][4]));
95+
else if (!strcmp(argv[i], "fp64"))
96+
bFp64 = true;
97+
}
98+
99+
cudaDeviceProp prop;
100+
101+
checkCuda( cudaSetDevice(deviceId) )
102+
;
103+
checkCuda( cudaGetDeviceProperties(&prop, deviceId) );
104+
printf("Device: %s\n", prop.name);
105+
printf("Transfer size (MB): %d\n", nMB);
106+
107+
printf("%s Precision\n", bFp64 ? "Double" : "Single");
108+
109+
if (bFp64) runTest<double>(deviceId, nMB);
110+
else runTest<float>(deviceId, nMB);
111+
}

0 commit comments

Comments
 (0)