From d176b3a854ca029bd0657d282f198f8da8c53552 Mon Sep 17 00:00:00 2001 From: Janet Wang <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:33:23 -0400 Subject: [PATCH 1/7] code --- stream_compaction/common.cu | 8 +++ stream_compaction/cpu.cu | 42 ++++++++++++- stream_compaction/efficient.cu | 108 ++++++++++++++++++++++++++++++++- stream_compaction/naive.cu | 32 +++++++++- stream_compaction/thrust.cu | 13 +++- 5 files changed, 196 insertions(+), 7 deletions(-) diff --git a/stream_compaction/common.cu b/stream_compaction/common.cu index 2ed6d63..7dbb08f 100644 --- a/stream_compaction/common.cu +++ b/stream_compaction/common.cu @@ -24,6 +24,9 @@ namespace StreamCompaction { */ __global__ void kernMapToBoolean(int n, int *bools, const int *idata) { // TODO + int index = threadIdx.x + (blockIdx.x * blockDim.x); + if (index >= n) return; + bools[index] = (idata[index] != 0); } /** @@ -33,6 +36,11 @@ namespace StreamCompaction { __global__ void kernScatter(int n, int *odata, const int *idata, const int *bools, const int *indices) { // TODO + int index = threadIdx.x + (blockIdx.x * blockDim.x); + if (index >= n) return; + if (bools[index] > 0) { + odata[indices[index]] = idata[index]; + } } } diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index 719fa11..3341a9c 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -20,6 +20,10 @@ namespace StreamCompaction { void scan(int n, int *odata, const int *idata) { timer().startCpuTimer(); // TODO + odata[0] = 0; + for (int i = 1; i < n; i++) { + odata[i] = idata[i - 1] + odata[i - 1]; + } timer().endCpuTimer(); } @@ -31,8 +35,17 @@ namespace StreamCompaction { int compactWithoutScan(int n, int *odata, const int *idata) { timer().startCpuTimer(); // TODO + int cnt = 0; + odata[0] = 0; + for (int i = 0; i < n; i++) { + if(idata[i] != 0) + { + odata[cnt] = idata[i]; + cnt++; + } + } timer().endCpuTimer(); - return -1; + return cnt; } /** @@ -43,8 +56,33 @@ namespace StreamCompaction { int compactWithScan(int n, int *odata, const int *idata) { timer().startCpuTimer(); // TODO + + // temporary array + int *temp = new int[n]; + for (int i = 0; i < n; i++) { + temp[i] = (idata[i] != 0); + } + int *temp2 = new int[n]; + + // scan + temp2[0] = 0; + for (int i = 1; i < n; i++) { + temp2[i] = temp[i - 1] + temp2[i - 1]; + } + int cnt = temp2[n - 1]; + + // scatter + for (int i = 0; i < n; i++) { + if (temp[i] > 0) + { + odata[temp2[i]] = idata[i]; + } + } + timer().endCpuTimer(); - return -1; + delete[] temp; + delete[] temp2; + return cnt; } } } diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 2db346e..898131a 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -3,6 +3,8 @@ #include "common.h" #include "efficient.h" +#define blockSize 128 + namespace StreamCompaction { namespace Efficient { using StreamCompaction::Common::PerformanceTimer; @@ -12,13 +14,65 @@ namespace StreamCompaction { return timer; } + __global__ void kernUpSweep(int n, int d, int* data) { + int index = threadIdx.x + (blockIdx.x * blockDim.x); + if (index >= n) return; + + int a = 1 << d; + int b = 1 << (d + 1); + if (index % b == 0) + { + data[index + b - 1] += data[index + a - 1]; + } + } + + __global__ void kernDownSweep(int n, int d, int* data){ + int index = threadIdx.x + (blockIdx.x * blockDim.x); + if (index >= n) return; + + int a = 1 << d; + int b = 1 << (d + 1); + if (index % b == 0) + { + int temp = data[index + b - 1]; + data[index + b - 1] += data[index + a - 1]; + data[index + a - 1] = temp; + } + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { - timer().startGpuTimer(); + // TODO + dim3 fullBlocksPerGrid((n + blockSize - 1) / blockSize); + int size = pow(2, ilog2ceil(n)); + + int* scan_array; + cudaMalloc((void**)&scan_array, size * sizeof(int)); + cudaMemset(scan_array, 0, size * sizeof(int)); + cudaMemcpy(scan_array, idata, size * sizeof(int), cudaMemcpyHostToDevice); + + timer().startGpuTimer(); + // Up sweep + for (int i = 0; i < ilog2ceil(n); i++) + { + kernUpSweep <<>> (size, i, scan_array); + checkCUDAError("kernUpSweep fails."); + } + cudaMemset(scan_array + size - 1, 0, sizeof(int)); + + // Down sweep + for (int i = ilog2ceil(n) - 1; i >= 0; i--) + { + kernDownSweep <<>> (size, i, scan_array); + checkCUDAError("kernDownSweep fails."); + } timer().endGpuTimer(); + + cudaMemcpy(odata, scan_array, n * sizeof(int), cudaMemcpyDeviceToHost); + cudaFree(scan_array); } /** @@ -31,10 +85,58 @@ namespace StreamCompaction { * @returns The number of elements remaining after compaction. */ int compact(int n, int *odata, const int *idata) { - timer().startGpuTimer(); + // TODO + dim3 fullBlocksPerGrid((n + blockSize - 1) / blockSize); + int size = pow(2, ilog2ceil(n)); + + int* iarray; + int* bool_array; + int* scan_array; + cudaMalloc((void**)&iarray, size * sizeof(int)); + cudaMalloc((void**)&bool_array, size * sizeof(int)); + cudaMalloc((void**)&scan_array, size * sizeof(int)); + cudaMemcpy(iarray, idata, size * sizeof(int), cudaMemcpyHostToDevice); + + timer().startGpuTimer(); + + // map to bool + Common::kernMapToBoolean<<>>(size, bool_array, iarray); + cudaMemcpy(scan_array, bool_array, size * sizeof(int), cudaMemcpyDeviceToDevice); + + // up sweep + for (int i = 0; i < ilog2ceil(n); i++) { + kernUpSweep <<>> (size, i, scan_array); + checkCUDAError("kernUpSweep fails."); + } + cudaMemset(scan_array + size - 1, 0, sizeof(int)); + + // down sweep + for (int i = ilog2ceil(n) - 1; i >= 0; i--) { + kernDownSweep <<>> (size, i, scan_array); + checkCUDAError("kernDownSweep fails."); + } + + // scatter + int* oarray; + cudaMalloc((void**)&oarray, size * sizeof(int)); + Common::kernScatter <<>>(size, oarray, iarray, bool_array, scan_array); + timer().endGpuTimer(); - return -1; + + int a = 0; + int b = 0; + cudaMemcpy(&a, scan_array + size - 1, sizeof(int), cudaMemcpyDeviceToHost); + cudaMemcpy(&b, bool_array + size - 1, sizeof(int), cudaMemcpyDeviceToHost); + int cnt = a + b; + cudaMemcpy(odata, oarray, cnt * sizeof(int), cudaMemcpyDeviceToHost); + + cudaFree(iarray); + cudaFree(oarray); + cudaFree(bool_array); + cudaFree(scan_array); + + return cnt; } } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 4308876..a758b78 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -11,15 +11,45 @@ namespace StreamCompaction { static PerformanceTimer timer; return timer; } + // TODO: __global__ + __global__ void kernNaiveScan(int *idata, int *odata, int n, int offset) { + int index = threadIdx.x + (blockIdx.x * blockDim.x); + if (index >= n) return; + if (index >= offset) { + odata[index] = idata[index] + idata[index - offset]; + } + else { + odata[index] = idata[index]; + } + } /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { - timer().startGpuTimer(); // TODO + int blockSize = 128; + dim3 fullBlocksPerGrid((n + blockSize - 1) / blockSize); + + int* iarray; + int* oarray; + cudaMalloc((void**)&iarray, n * sizeof(int)); + cudaMalloc((void**)&oarray, n * sizeof(int)); + cudaMemcpy(iarray, idata, n * sizeof(int), cudaMemcpyHostToDevice); + + timer().startGpuTimer(); + for (int i = 1; i <= ilog2ceil(n); i++) { + int offset = pow(2, i - 1); + kernNaiveScan <<>> (iarray, oarray, n, offset); + cudaMemcpy(iarray, oarray, n * sizeof(int), cudaMemcpyDeviceToDevice); + } timer().endGpuTimer(); + + cudaMemcpy(odata + 1, oarray, n * sizeof(int), cudaMemcpyDeviceToHost); + odata[0] = 0; + cudaFree(iarray); + cudaFree(oarray); } } } diff --git a/stream_compaction/thrust.cu b/stream_compaction/thrust.cu index 1def45e..7b37fa3 100644 --- a/stream_compaction/thrust.cu +++ b/stream_compaction/thrust.cu @@ -18,11 +18,22 @@ namespace StreamCompaction { * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { - timer().startGpuTimer(); + // TODO use `thrust::exclusive_scan` // example: for device_vectors dv_in and dv_out: // thrust::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); + + thrust::device_vector dv_in(idata, idata+n); + thrust::device_vector dv_out(n); + + timer().startGpuTimer(); + thrust::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); timer().endGpuTimer(); + + for (int i = 0; i < n; i++) + { + odata[i] = dv_out[i]; + } } } } From f130248f32f798b1d3c904f96b7fa84dd0e619ae Mon Sep 17 00:00:00 2001 From: wxc <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:57:44 -0400 Subject: [PATCH 2/7] Add files via upload --- nsight.PNG | Bin 0 -> 34367 bytes pj2.txt | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 nsight.PNG create mode 100644 pj2.txt diff --git a/nsight.PNG b/nsight.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c86a8902b831d23cd3297aa38c80c999508e0144 GIT binary patch literal 34367 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 literal 0 HcmV?d00001 diff --git a/pj2.txt b/pj2.txt new file mode 100644 index 0000000..91d6f5a --- /dev/null +++ b/pj2.txt @@ -0,0 +1,53 @@ + +**************** +** SCAN TESTS ** +**************** + [ 47 40 21 2 41 34 26 16 47 18 22 27 9 ... 12 0 ] +==== cpu scan, power-of-two ==== + elapsed time: 0.0004ms (std::chrono Measured) + [ 0 47 87 108 110 151 185 211 227 274 292 314 341 ... 6241 6253 ] +==== cpu scan, non-power-of-two ==== + elapsed time: 0.0003ms (std::chrono Measured) + [ 0 47 87 108 110 151 185 211 227 274 292 314 341 ... 6148 6160 ] + passed +==== naive scan, power-of-two ==== + elapsed time: 0.047456ms (CUDA Measured) + passed +==== naive scan, non-power-of-two ==== + elapsed time: 0.046528ms (CUDA Measured) + passed +==== work-efficient scan, power-of-two ==== + elapsed time: 0.051264ms (CUDA Measured) + passed +==== work-efficient scan, non-power-of-two ==== + elapsed time: 0.051392ms (CUDA Measured) + passed +==== thrust scan, power-of-two ==== + elapsed time: 0.037952ms (CUDA Measured) + passed +==== thrust scan, non-power-of-two ==== + elapsed time: 0.03808ms (CUDA Measured) + passed + +***************************** +** STREAM COMPACTION TESTS ** +***************************** + [ 0 1 3 2 1 3 2 1 3 0 0 3 0 ... 0 0 ] +==== cpu compact without scan, power-of-two ==== + elapsed time: 0.0006ms (std::chrono Measured) + [ 1 3 2 1 3 2 1 3 3 3 2 1 3 ... 1 2 ] + passed +==== cpu compact without scan, non-power-of-two ==== + elapsed time: 0.0005ms (std::chrono Measured) + [ 1 3 2 1 3 2 1 3 3 3 2 1 3 ... 1 1 ] + passed +==== cpu compact with scan ==== + elapsed time: 0.0013ms (std::chrono Measured) + [ 1 3 2 1 3 2 1 3 3 3 2 1 3 ... 1 2 ] + passed +==== work-efficient compact, power-of-two ==== + elapsed time: 0.07184ms (CUDA Measured) + passed +==== work-efficient compact, non-power-of-two ==== + elapsed time: 0.07296ms (CUDA Measured) +Press any key to continue . . . \ No newline at end of file From 206a0ca05b8d5db7f277eea2ef34f19a6da4f971 Mon Sep 17 00:00:00 2001 From: wxc <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:00:20 -0400 Subject: [PATCH 3/7] Update README.md --- README.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0e38ddb..919e326 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,20 @@ CUDA Stream Compaction **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 2** -* (TODO) YOUR NAME HERE - * (TODO) [LinkedIn](), [personal website](), [twitter](), etc. -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +* Janet Wang + * https://xchennnw.github.io/ +* Tested on: Windows 11, i7-12700H @ 2.30GHz 16GB, Nvidia Geforce RTX 3070 Ti 8054MB -### (TODO: Your README) - -Include analysis, etc. (Remember, this is public, so don't put -anything here that you don't want to share with the world.) +### TODO implemented +* CPU Scan & Stream Compaction +* Naive GPU Scan Algorithm +* Work-Efficient GPU Scan & Stream Compaction +* Scan using Thrust + +### Project Description +This project is about GPU stream compaction in CUDA, including a few different versions of the Scan (Prefix Sum) algorithm: a CPU version, GPU naive scan, GPU "work-efficient" scan, and GPU scan using thrust. It also includes GPU stream compaction using the above algorithms. +### Performance Analysis +![](scan2.png) +![](scan1.png) +![](nsight.png) From e105effee692abda684a98a0ee08cbf198f94543 Mon Sep 17 00:00:00 2001 From: Janet Wang <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:00:46 -0400 Subject: [PATCH 4/7] bug fix & images --- scan1.png | Bin 0 -> 41580 bytes scan2.png | Bin 0 -> 48291 bytes src/main.cpp | 2 +- stream_compaction/efficient.cu | 3 ++- stream_compaction/thrust.cu | 5 +---- 5 files changed, 4 insertions(+), 6 deletions(-) create mode 100644 scan1.png create mode 100644 scan2.png diff --git a/scan1.png b/scan1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d82a77a52645cb950d32ab69294df52f649ffba GIT binary patch literal 41580 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�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 literal 0 HcmV?d00001 diff --git a/scan2.png b/scan2.png new file mode 100644 index 0000000000000000000000000000000000000000..c4ec97dd928cfce3c0e52ea51a2aff626ec563c3 GIT binary patch literal 48291 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 M #include "testing_helpers.hpp" -const int SIZE = 1 << 8; // feel free to change the size of array +const int SIZE = 1 << 16; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 898131a..f18cfd9 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -96,7 +96,8 @@ namespace StreamCompaction { cudaMalloc((void**)&iarray, size * sizeof(int)); cudaMalloc((void**)&bool_array, size * sizeof(int)); cudaMalloc((void**)&scan_array, size * sizeof(int)); - cudaMemcpy(iarray, idata, size * sizeof(int), cudaMemcpyHostToDevice); + cudaMemset(iarray, 0, n * sizeof(int)); + cudaMemcpy(iarray, idata, n * sizeof(int), cudaMemcpyHostToDevice); timer().startGpuTimer(); diff --git a/stream_compaction/thrust.cu b/stream_compaction/thrust.cu index 7b37fa3..282bbf1 100644 --- a/stream_compaction/thrust.cu +++ b/stream_compaction/thrust.cu @@ -30,10 +30,7 @@ namespace StreamCompaction { thrust::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); timer().endGpuTimer(); - for (int i = 0; i < n; i++) - { - odata[i] = dv_out[i]; - } + thrust::copy(dv_out.begin(), dv_out.end(), odata); } } } From dec579d522657efda5b01ed655d9e4920be0c2af Mon Sep 17 00:00:00 2001 From: wxc <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:02:19 -0400 Subject: [PATCH 5/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 919e326..20b0b09 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,4 @@ This project is about GPU stream compaction in CUDA, including a few different v ### Performance Analysis ![](scan2.png) ![](scan1.png) -![](nsight.png) +![](nsight.PNG) From 545abe854c8f487834ebd9345a31dd1607fc1b7a Mon Sep 17 00:00:00 2001 From: wxc <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:50:58 -0400 Subject: [PATCH 6/7] Update README.md --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/README.md b/README.md index 20b0b09..85ba673 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,65 @@ This project is about GPU stream compaction in CUDA, including a few different v ### Performance Analysis ![](scan2.png) ![](scan1.png) +* When the array size is greater than 2^8, thrus scan always has the best performance. +* When the array size is under 2^16, CPU scan is faster than both of the GPU naive scan and work-efficient scan. The rational explanation could be the cost of GPU reading data from global memory is a relatively large part of time cost when array size is small. +* The GPU efficient scan perferms better than naive only after the the array size is greater than 2^16. I am actually confused about this point. +* When the array size is greater than 2^16, the rank of the methods becomes relatively stable: thrust > GPU efficient > GPU naive > CPU ![](nsight.PNG) +This is the Nsight timeline for the execution of GPU scan using thrust. It seems like cudaMemcpyAsync() and cudaStreamSynchronize are used here, but to be honest I do not quite understand what happens in these two functions and how they significantly improve the performance. + +### Output of the test program +SIZE = 1 << 24 + +**************** +** SCAN TESTS ** +**************** + [ 43 2 2 48 43 19 31 48 40 42 13 19 31 ... 6 0 ] +==== cpu scan, power-of-two ==== + elapsed time: 41.2005ms (std::chrono Measured) + [ 0 43 45 47 95 138 157 188 236 276 318 331 350 ... 410823510 410823516 ] +==== cpu scan, non-power-of-two ==== + elapsed time: 43.9688ms (std::chrono Measured) + [ 0 43 45 47 95 138 157 188 236 276 318 331 350 ... 410823427 410823469 ] + passed +==== naive scan, power-of-two ==== + elapsed time: 26.7661ms (CUDA Measured) + passed +==== naive scan, non-power-of-two ==== + elapsed time: 27.9169ms (CUDA Measured) + passed +==== work-efficient scan, power-of-two ==== + elapsed time: 12.5882ms (CUDA Measured) + passed +==== work-efficient scan, non-power-of-two ==== + elapsed time: 13.1602ms (CUDA Measured) + passed +==== thrust scan, power-of-two ==== + elapsed time: 1.37734ms (CUDA Measured) + passed +==== thrust scan, non-power-of-two ==== + elapsed time: 1.35168ms (CUDA Measured) + passed + +***************************** +** STREAM COMPACTION TESTS ** +***************************** + [ 0 3 2 0 0 0 1 3 1 0 1 3 2 ... 3 0 ] +==== cpu compact without scan, power-of-two ==== + elapsed time: 49.1391ms (std::chrono Measured) + [ 3 2 1 3 1 1 3 2 1 3 3 1 3 ... 1 3 ] + passed +==== cpu compact without scan, non-power-of-two ==== + elapsed time: 51.6044ms (std::chrono Measured) + [ 3 2 1 3 1 1 3 2 1 3 3 1 3 ... 1 1 ] + passed +==== cpu compact with scan ==== + elapsed time: 116.318ms (std::chrono Measured) + [ 3 2 1 3 1 1 3 2 1 3 3 1 3 ... 1 3 ] + passed +==== work-efficient compact, power-of-two ==== + elapsed time: 12.9027ms (CUDA Measured) + passed +==== work-efficient compact, non-power-of-two ==== + elapsed time: 13.2913ms (CUDA Measured) + passed From 2a9a9c473de20c8ece5e30b79adf2ed5da32c41a Mon Sep 17 00:00:00 2001 From: wxc <55120659+xchennnw@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:52:12 -0400 Subject: [PATCH 7/7] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 85ba673..d12a56b 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ This is the Nsight timeline for the execution of GPU scan using thrust. It seems ### Output of the test program SIZE = 1 << 24 - +``` **************** ** SCAN TESTS ** **************** @@ -81,3 +81,4 @@ SIZE = 1 << 24 ==== work-efficient compact, non-power-of-two ==== elapsed time: 13.2913ms (CUDA Measured) passed +```