# <center>Parallel Programming NYCU Fall 2022 HW6
<p class="text-right">
310552035 張竣傑
## Q1
**Explain your implementation. How do you optimize the performance of convolution?**
在hostFE.c中設定 local work size = 64, global work size = imageWidth x imageHeight,使得每個pixel都可以進行平行處理。接著基於作業給的 serialConv.c 中的 serialConv() 將對應 pixel 的 convolution 計算出來。
* Optimize the performace of convolution:
原本的seriel的做法如下:

在進行kernel運算的時候每次都會先判斷是否超出圖片邊界,這樣會讓整體的效能降低。所以直覺的作法就是把這個判斷拉出去,事先進行計算,讓我們可以先知道k跟l要計算的範圍在哪裡,以減少判斷。再來第二個需要考慮的點是:kernel再計算的時候假如遇到0可以不用再進行計算,所以這邊可以額外加速的地方在於我們可以事先判斷fiter的某個位置是否為0,假如是的話,就不參與sum的計算,當filter中0的數量很多的時候可以些微加快速度。(或是可以用Table紀錄哪些地方有值,再進行計算的時候就用記錄的位置去計算,可以達到更快的速度。)
實際整體做法如下:

## Q2
**Rewrite the program using CUDA.**
1. Explain your CUDA implementation
設定 threadsPerBlock = 8 x 8,numBlocks = (imageWidth / threadsPerBlock.x, imageHeight / threadsPerBlock.y)和 OpenCL 一樣確保圖片的每一個 pixel 都有 thread 對應做平行處理



2. plot a chart to show the performance difference between using OpenCL and CUDA

3. explain the result.
在相同算法和優化的實作下,可以看見三種不同 filter 的情況中, CUDA 會比 OpenCL 稍快一點。我認為, CUDA 是專門優化在 NVIDIA 設備上的平行化程式,相較於 OpenCL 雖然他是支援跨平台跨設備的程式編寫框架。但整體的優化效果沒有 CUDA 好。
結論: 對於 NVIDIA 的 GPU 在效能的比較上, CUDA 的表現會比 OpenCL 好。