From 2e0dfa0db9b45faf72eeb75689a104dc33a1624d Mon Sep 17 00:00:00 2001 From: Helen Date: Thu, 24 Sep 2020 23:41:14 -0400 Subject: [PATCH] finished hw --- README.md | 84 +++++++++++++-- img/performance.png | Bin 0 -> 128305 bytes src/main.cpp | 2 +- stream_compaction/common.cu | 17 +++- stream_compaction/cpu.cu | 57 ++++++++++- stream_compaction/efficient.cu | 180 ++++++++++++++++++++++++++++++++- stream_compaction/naive.cu | 63 +++++++++++- stream_compaction/thrust.cu | 21 +++- 8 files changed, 400 insertions(+), 24 deletions(-) create mode 100644 img/performance.png diff --git a/README.md b/README.md index 0e38ddb..a1b40da 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,84 @@ 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) +* Hanyu Liu + * [personal website](http://liuhanyu.net/) +* Tested on: Windows 10, Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz 16.0GB, GeForce GTX 1050 (Personal) + +### Summary of Project + +In this project, I implemented stream compaction, which simply removes `0`s from an array of `1`s, on both the CPU and the GPU in CUDA. Stream compaction uses the scan (Prefix Sum) Algorithm, and in this project, I implemented four different scan methods: 1) Scan on the CPU, 2) Naive, 3) Work-Efficient, and 4) Using Thrust. Furthermore, GPU stream compaction also needed additional kernels to generate a boolean mask and scatter, which I also implemented. With the help of these functions, I was able to implement stream compaction on both the GPU and the CPU. + + + +Stream compaction is widely used, and will be used to accelerate my future path tracer project. + + + +### Performance Analysis + +![](img/performance.png) + +1. For the Thrust implementation, the runtime is significantly lower than the other implementations. This is possibly due to the small amount of memory copy as it alters the data in place without the need for extra buffers. + +2. Here, we see that the Naive and Work-Efficient scans both take much longer than the CPU scan at large array sizes even though we are altering the array in parallel on the GPU. In fact, the work-efficient scan takes much longer than the naive scan. Both GPU implementations take longer possibly because there is more overhead from the kernel calls. As for the difference between Naive and Work-Efficient scans, the work-efficient scan takes two for loops on larger, padded arrays, which causes it to be slower than the naive implementation. Ultimately, the bottle-neck is the number of additions we have to perform, which is log base2 of n. The rest of the performance depends on memory allocation, the cache, and overhead, in which case, CPU would win out. + +3. ``` + + **************** + ** SCAN TESTS ** + **************** + [ 3 5 18 11 7 47 39 47 30 45 5 9 40 ... 23 0 ] + ==== cpu scan, power-of-two ==== + elapsed time: 0.0023ms (std::chrono Measured) + [ 0 3 8 26 37 44 91 130 177 207 252 257 266 ... 24162 24185 ] + ==== cpu scan, non-power-of-two ==== + elapsed time: 0.0051ms (std::chrono Measured) + [ 0 3 8 26 37 44 91 130 177 207 252 257 266 ... 24142 24149 ] + passed + ==== naive scan, power-of-two ==== + elapsed time: 0.023552ms (CUDA Measured) + passed + ==== naive scan, non-power-of-two ==== + elapsed time: 0.022528ms (CUDA Measured) + passed + ==== work-efficient scan, power-of-two ==== + elapsed time: 0.1024ms (CUDA Measured) + passed + ==== work-efficient scan, non-power-of-two ==== + elapsed time: 0.132096ms (CUDA Measured) + passed + ==== thrust scan, power-of-two ==== + elapsed time: 0.079872ms (CUDA Measured) + passed + ==== thrust scan, non-power-of-two ==== + elapsed time: 0.090336ms (CUDA Measured) + passed + + ***************************** + ** STREAM COMPACTION TESTS ** + ***************************** + [ 3 3 2 1 3 3 3 3 0 1 3 3 2 ... 1 0 ] + ==== cpu compact without scan, power-of-two ==== + elapsed time: 0.0073ms (std::chrono Measured) + [ 3 3 2 1 3 3 3 3 1 3 3 2 2 ... 2 1 ] + passed + ==== cpu compact without scan, non-power-of-two ==== + elapsed time: 0.0074ms (std::chrono Measured) + [ 3 3 2 1 3 3 3 3 1 3 3 2 2 ... 3 1 ] + passed + ==== cpu compact with scan ==== + elapsed time: 0.0363ms (std::chrono Measured) + [ 3 3 2 1 3 3 3 3 1 3 3 2 2 ... 2 1 ] + passed + ==== work-efficient compact, power-of-two ==== + elapsed time: 0.192512ms (CUDA Measured) + passed + ==== work-efficient compact, non-power-of-two ==== + elapsed time: 0.171008ms (CUDA Measured) + passed + Press any key to continue . . . + ``` -### (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.) diff --git a/img/performance.png b/img/performance.png new file mode 100644 index 0000000000000000000000000000000000000000..b2f3a9828e05f54f1574a336e322741789b1c0cd GIT binary patch literal 128305 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

    YVrBesNAGdSwkvr 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

      yFs_B?5Rjqyh1neBhArT@(~O@0WxkZ@7BJs~ zMr+#bTwHNH$cf0)FKh@PrsM4^dbb1JF5 z3A$e3b{U*}DcP#Eq_~T1Qs&4Hz%3L33gx&oB6`B>sh;JJ5dqMPIH--%i?Nj1XL>Px zurUnWP=Y#7P#_=$W=>7zt5}zoNwjRq8vzxkdtoGodk%l|D=rP#yB6dOE*m|MkmwGt zAFidTus|l(r9n3#urpAD=9vI+^n1|)$yx9v`k6>ATNaQ-tH*(dDYZNLwZOPvEMO== z726dQ)H-^H;#0vk1QGVCFjsn3jg0xOKsn49IjFoEj+gNat(Z}$s|Bp9z%gDTLWle| zkxAg4Tr>zpK|+sTZ-$kZAR~f;>An?@xle75C1{VE9e-RM`x#jCP1D?Yv4`Z|=-u94 z1=?_yGaLGzseId246jxBs}{3;K8;eGnm8{$$^BK9n@Ni*2S@HD-{k;NDeX(t_mq8~W!7YBBg&F`!cqcfzN_BFs1G?_EUF??LEB7z|5& z8^?4ep@CBqonxb+N{`Qx;y$Ukze0xG;)SSTg630jH;g7S;BJ_FrpP-M|8sLKj$Oi? zJywE^lYP-iPQWBJAGOt7IWou&lB}BWq-gs>zM~#g-_Zpe1g}3eu=#MVrsr;F$qf&O zCD}z<56%d>v^+&em<7Cl#A-|dfFjBkghIEDLG_L;KTpGYp?9M1E$rH;-Cu7Y%hWTJ z^!5obPR*vVp|nAQ_FBN1RsYJS9GwSAe-7B)44CSen|fukB?aS>{i1pt>E{P()Mmay z3Nn9z{`tiXV~fA8NK^qQ7EcmZ<+?~|^CpuQ_y?Wt90!bq`i5$$G*hWb7W%EX*etW~ zj~bSy;$?x9Yt0R+<$soG{T?oT0h+A*lphtW7v$VKe9uBxGs&t_=7D-`##{-AQc}ht1>1pGaOm z;q|nm&OS_J5*qDA8ui|q3gf+oATDoT(@SR>Tv^^=9t&=4n}10b`6^0=eRmSecVvfb zxb$VK>>VS00shkE?@W+EeRs~crKY1xXj6jg20L(|xE-pI+xkla?H?CDef7&={>rIV<=c!)%kFv2oge-x zX6==ow`AA<`P=l~TU;bI!0wjo-|DhEUUTiER~8=!nv8;L+rojXTx$A(2S%)qeY@h^ zm2+2aKJEh^(JVUeqHFE;O6~OL&+Oyho_e?Q=AWP8v#)-A3{-Gyv(4+u!21i!mYqAN z9e%xi_3Qp$C!X(pbx&6Q<)gpp(Q9L3<)0aEb-%ke|HjVmf6rtsJ$LqY;P5Z%2zC{R}0O`mcFyReQNRZ^#8Z^TF3qE_paT)(YSx!%<}73|9-w-cxURa z=fGf!jJ@+WZuRHSTOZ2>e(%4#vH1O;@-^Fno*$q0RD1V|wO4*_G`3D}`*~;2)Vsy* zpKHUdgVT@CduhC@;!FCz;=Fq^t*W<8wX)x~_?`6bpzl3zSNuL^_vk9nDYh@07IB|S zFAe;^uQzsO^|@`IUi`edzwCWqxUK%Xy7^aYKW_!aMe=UBz1z?2e?N8J)uVUc@3gXy zx6V7h`1$>_-(!J+y-~aL{O@^hVGapTU$^f5$BE~wukN+BTipG9e&M}SbBjN}`?0F} z{`qsei=NM0{Htf #include "testing_helpers.hpp" -const int SIZE = 1 << 8; // feel free to change the size of array +const int SIZE = 1000; // 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/common.cu b/stream_compaction/common.cu index 2ed6d63..cc36929 100644 --- a/stream_compaction/common.cu +++ b/stream_compaction/common.cu @@ -23,7 +23,15 @@ namespace StreamCompaction { * which map to 0 will be removed, and elements which map to 1 will be kept. */ __global__ void kernMapToBoolean(int n, int *bools, const int *idata) { - // TODO + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + if (idata[k] != 0) { + bools[k] = 1; + } + else { + bools[k] = 0; + } } /** @@ -32,7 +40,12 @@ namespace StreamCompaction { */ __global__ void kernScatter(int n, int *odata, const int *idata, const int *bools, const int *indices) { - // TODO + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + if (bools[k] == 1) { + odata[indices[k]] = idata[k]; + } } } diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index 719fa11..645af9b 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -19,7 +19,11 @@ namespace StreamCompaction { */ void scan(int n, int *odata, const int *idata) { timer().startCpuTimer(); - // TODO + // compute an exclusive prefix sum + odata[0] = 0; + for (int i = 1; i < n; i++) { + odata[i] = odata[i - 1] + idata[i - 1]; + } timer().endCpuTimer(); } @@ -30,9 +34,28 @@ namespace StreamCompaction { */ int compactWithoutScan(int n, int *odata, const int *idata) { timer().startCpuTimer(); - // TODO + int elements_remaining = 0; + for (int i = 0; i < n; i++) { + if (idata[i] != 0) { + odata[elements_remaining] = idata[i]; + elements_remaining++; + } + } timer().endCpuTimer(); - return -1; + return elements_remaining; + } + + /* + * Helper Function because I seem to be having issues when I start the timer again + * Same as scan function earlier, just without the timer + * From Piazza @110 + */ + void cpu_scan(int n, int* odata, const int* idata) { + // compute an exclusive prefix sum + odata[0] = 0; + for (int i = 1; i < n; i++) { + odata[i] = odata[i - 1] + idata[i - 1]; + } } /** @@ -42,9 +65,33 @@ namespace StreamCompaction { */ int compactWithScan(int n, int *odata, const int *idata) { timer().startCpuTimer(); - // TODO + // fill temp array with 0 if idata is 0 or 1 otherwise + int* temp_array = new int[n]; + for (int i = 0; i < n; i++) { + if (idata[i] == 0) { + temp_array[i] = 0; + } + else temp_array[i] = 1; + } + + // run exclusive scan on temporary array + int* scanned_array = new int[n]; + cpu_scan(n, scanned_array, temp_array); + + // scatter + for (int j = 0; j < n; j++) { + if (temp_array[j] == 1) { + // write element + odata[scanned_array[j]] = idata[j]; + } + } + + // cleanup + int result = scanned_array[n - 1]; timer().endCpuTimer(); - return -1; + delete[] temp_array; + delete[] scanned_array; + return result; } } } diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 2db346e..47b709c 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -12,13 +12,106 @@ namespace StreamCompaction { return timer; } + __global__ void kernaldownsweep(int n, int d, int* input) { + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + // 2 ^ d + int pow_2d = 1 << d; + // 2 ^ (d+1) + int pow_2d1 = 1 << (d + 1); + + // we want the even indices to add into the odd indices + if (k % pow_2d1 == 0) { + int t = input[k + pow_2d - 1]; + input[k + pow_2d - 1] = input[k + pow_2d1 - 1]; + input[k + pow_2d1 - 1] += t; + } + } + + __global__ void kernalupsweep(int n, int d, int* input) { + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + // 2 ^ d + int pow_2d = 1 << d; + // 2 ^ (d+1) + int pow_2d1 = 1 << (d + 1); + + // we want the even indices to add into the odd indices + if (k % pow_2d1 == 0) { + input[k + pow_2d1 - 1] += input[k + pow_2d - 1]; + } + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { + + // The idea is to build a balanced binary tree on the input data and + // sweep it to and from the root to compute the prefix sum. A binary + // tree with n leaves has d = log2 n levels, and each level d has 2 d nodes. + + int padded_size = 1 << ilog2ceil(n); + int* temp_array = new int[padded_size]; + + // make sure to pad temp array with 0s! + // to do: is this faster or cuda memcpying 0s faster? hmm + for (int i = 0; i < padded_size; i++) { + if (i < n) { + temp_array[i] = idata[i]; + } + else { + temp_array[i] = 0; + } + } + + // initialize some temporary buffers to write in place + // your intermediate array sizes will need to be rounded to the next power of two. + int* temp_input; + cudaMalloc((void**)&temp_input, padded_size * sizeof(int)); + // fill temp input buffer with the padded array above + cudaMemcpy(temp_input, temp_array, padded_size * sizeof(int), cudaMemcpyHostToDevice); + + // set up the blocks and grids + int blockSize = 64; + dim3 blocksPerGrid((padded_size + blockSize - 1) / blockSize); + dim3 threadsPerBlock(blockSize); + timer().startGpuTimer(); - // TODO + + // The algorithm consists of two phases : + // the reduce phase(also known as the up - sweep phase) + // and the down - sweep phase. + + // up sweep phase + for (int d = 0; d < ilog2ceil(n); d++) { + kernalupsweep << > > (padded_size, d, temp_input); + } + + // replace last index as 0 + int zero = 0; + cudaMemcpy(temp_input + padded_size - 1, &zero, sizeof(int), cudaMemcpyHostToDevice); + + // downsweep phase + for (int d = ilog2ceil(n) - 1; d >= 0; d--) { + kernaldownsweep << > > (padded_size, d, temp_input); + } + timer().endGpuTimer(); + + // copy from GPU to CPU + cudaMemcpy(temp_array, temp_input, padded_size * sizeof(int), cudaMemcpyDeviceToHost); + + // copy into outdata + for (int i = 0; i < n; i++) { + odata[i] = temp_array[i]; + } + + // cleanup + cudaFree(temp_input); + delete[] temp_array; } /** @@ -31,10 +124,87 @@ namespace StreamCompaction { * @returns The number of elements remaining after compaction. */ int compact(int n, int *odata, const int *idata) { - timer().startGpuTimer(); - // TODO - timer().endGpuTimer(); - return -1; + // we want to setup stuff for scans because we don't want the setup to be within the timer + // your intermediate array sizes will need to be rounded to the next power of two. + int padded_size = 1 << ilog2ceil(n); + int* temp_array = new int[padded_size]; + + int* temp_bool; // stores the bool array on gpu + cudaMalloc((void**)&temp_bool, padded_size * sizeof(int)); + + int* temp_scan_output; // stores the scanned bool array + cudaMalloc((void**)&temp_scan_output, padded_size * sizeof(int)); + + // make sure to pad temp array with 0s! + // to do: is this faster or cuda memcpying 0s faster? hmm + for (int i = 0; i < padded_size; i++) { + if (i < n) { + temp_array[i] = idata[i]; + } + else { + temp_array[i] = 0; + } + } + + int* temp_input; // stores the padded input on the gpu + cudaMalloc((void**)&temp_input, padded_size * sizeof(int)); + // fill with padded data from above + cudaMemcpy(temp_input, idata, n * sizeof(int), cudaMemcpyHostToDevice); + + int* temp_output; // stores the output of the scatter on the gpu + cudaMalloc((void**)&temp_output, padded_size * sizeof(int)); + + // set up the blocks and grids + int blockSize = 128; + dim3 threadsPerBlock(blockSize); + dim3 blocksPerGrid((padded_size + blockSize - 1) / blockSize); + + timer().startGpuTimer(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // similar to the cpu... we want to: + // fill temp array with 0 if idata is 0 or 1 otherwise + // ================= MAP TO BOOL ======================= + Common::kernMapToBoolean << > > (padded_size, temp_bool, temp_input); + + // ================= SCAN =========================== + // The algorithm consists of two phases : + // the reduce phase(also known as the up - sweep phase) + // and the down - sweep phase. + + cudaMemcpy(temp_scan_output, temp_bool, padded_size * sizeof(int), cudaMemcpyDeviceToDevice); + + // up sweep phase + for (int d = 0; d < ilog2ceil(n); d++) { + kernalupsweep << > > (padded_size, d, temp_scan_output); + } + + // replace last index as 0 + int zero = 0; + cudaMemcpy(temp_scan_output + padded_size - 1, &zero, sizeof(int), cudaMemcpyHostToDevice); + + // downsweep phase + for (int d = ilog2ceil(n) - 1; d >= 0; d--) { + kernaldownsweep << > > (padded_size, d, temp_scan_output); + } + + // ================= SCATTER ======================= + Common::kernScatter << > > (padded_size, temp_output, temp_input, temp_bool, temp_scan_output); + timer().endGpuTimer(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // we want to copy information from gpu to cpu now + cudaMemcpy(odata, temp_output, padded_size * sizeof(int), cudaMemcpyDeviceToHost); + // we also want to print the result of the scan so we can count how many non-zeros there are + int result = -1; + cudaMemcpy(&result, temp_scan_output + padded_size - 1, sizeof(int), cudaMemcpyDeviceToHost); + + // cleanup + cudaFree(temp_output); + cudaFree(temp_input); + cudaFree(temp_bool); + cudaFree(temp_scan_output); + delete[] temp_array; + + return result; } } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 4308876..1143d83 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -11,15 +11,74 @@ namespace StreamCompaction { static PerformanceTimer timer; return timer; } - // TODO: __global__ + + __global__ void kernalNaiveScan(int n, int d, int* input, int* output) { + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + // if k >= 2 ^ (d - 1) <-- see example 2 in Ch 39 Patch + if (k >= (1 << (d - 1))) { + output[k] = input[k - (1 << (d - 1))] + input[k]; + } + else { + output[k] = input[k]; + } + } + + __global__ void kernalInc2Exc(int n, int* input, int* output) { + int k = (blockIdx.x * blockDim.x) + threadIdx.x; + if (k >= n) return; + + // shift everything to the right + // the default is 0 + if (k == 0) { + output[k] = 0; + } + else { + output[k] = input[k - 1]; + } + } /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ void scan(int n, int *odata, const int *idata) { + // set up the blocks and grids + int blockSize = 64; + dim3 blocksPerGrid((n + blockSize - 1) / blockSize); + dim3 threadsPerBlock(blockSize); + + // initialize some temporary buffers to write in place + int* temp_input; + cudaMalloc((void**)&temp_input, n * sizeof(int)); + // fill temp input buffer with the original input + cudaMemcpy(temp_input, idata, n * sizeof(int), cudaMemcpyHostToDevice); + + int* temp_output; + cudaMalloc((void**)&temp_output, n * sizeof(int)); + timer().startGpuTimer(); - // TODO + // iterate through for d = 1 to d = ilog2ceil(n) + for (int d = 1; d <= ilog2ceil(n); d++) { + // during each time, we want to call kernel to parallel scan + // from input to output + kernalNaiveScan<<>>(n, d, temp_input, temp_output); + + // remember to swap the buffers! + std::swap(temp_input, temp_output); + } + + // we want an exclusive scan so we have to convert + kernalInc2Exc << > > (n, temp_input, temp_output); + timer().endGpuTimer(); + + // now we want to write everything to our real output buffer + cudaMemcpy(odata, temp_output, n * sizeof(int), cudaMemcpyDeviceToHost); + + // cleanup + cudaFree(temp_input); + cudaFree(temp_output); } } } diff --git a/stream_compaction/thrust.cu b/stream_compaction/thrust.cu index 1def45e..19d02b5 100644 --- a/stream_compaction/thrust.cu +++ b/stream_compaction/thrust.cu @@ -17,12 +17,27 @@ namespace StreamCompaction { /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ + + // used help from: https://docs.nvidia.com/cuda/thrust/index.html#:~:text=As%20the%20names%20suggest%2C%20host_vector%20is%20stored%20in,any%20data%20type%29%20that%20can%20be%20resized%20dynamically. void scan(int n, int *odata, const int *idata) { + + // create a host vector + thrust::host_vector host_vector(n); + // initialize individual elements + thrust::copy(idata, idata + n, host_vector.begin()); + + // create a device vector from host vector + thrust::device_vector dv_in = host_vector; + thrust::device_vector dv_out(n); + 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::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); + timer().endGpuTimer(); + + thrust::copy(dv_out.begin(), dv_out.end(), odata); + } } }