HW6 Report === ###### tags: `Parallel Programming 2020` ## Q1 我做了以下幾點來最佳化我的程式 ### Replace `clCreateImage` with `clCreateBuffer` 使用 `clcreateBuffer` 而不是 `clCreateImage` 可以加快速度,我認爲的原因是因爲 `clcreateBuffer` 依賴這 `cl_image_desc` 這個 object ,這看起來又是對 raw memory bytes 更高一層的包裝,或許就是這樣其效果不如直接處理記憶體 ### Tuning work group size work-group size, a.k.a. local-work size,定義爲一個 work group 擁有多少 work items 如果 work-group size 太小,代表說 work group 的數量就會很多,造成計算資源的浪費;但如果 work-group size 太大,work group 數量很少,導致平行化的效果會不顯著,所以要找到一個適合的 work-group size 在作業中經過多次的實驗,我最後設定 worker-group size 爲 8 x 8 效果爲最好 ### Compress filter array 因爲 filter 可能會存在很多 0 的元素,這樣去乘以 image 上面的任何一個 pixel 都會跟沒乘一樣,因此可以先預處理 filter,把非零元素與相對應的座標位置挑出來,再傳進去 kernel function ,這樣就可以少處理幾個 filter 元素 ## Q2 ### Subtask1 首先我用了 `cudaMalloc` 來爲 `filter`, `inputImage`, `outputImage` 在 GPU 分配記憶體,然後再利用 `cudaMemcpy` 把 filter 和 inputImage 的資料搬過去 接著我設定每個 block 的大小是 8 * 8 ,代表一個 block 有 8 * 8 = 64 個 threads ,然後讓每個 thread 去處理一個 pixel 以算出 filtered 後的 pixel,每個 thread 算完後在用 `cudaMemcpy` 把 `outputImage` 複製回 host 這是我用 `nvprof` 跑 `filter1.csv` 的結果 ``` Reading filter data from filter1.csv Filter width: 7 Reading input image from input.bmp width = 600 height = 400 ==19641== NVPROF is profiling process 19641, command: ./conv [conv cuda]: [0.835] ms Writing output image to output.bmp ==19641== Profiling application: ./conv ==19641== Profiling result: Type Time(%) Time Calls Avg Min Max Name GPU activities: 66.16% 2.9864ms 10 298.64us 297.99us 299.01us convolution(int, float const *, int, int, float const *, float*) 17.27% 779.46us 10 77.946us 73.760us 115.17us [CUDA memcpy DtoH] 16.57% 748.07us 20 37.403us 736ns 75.072us [CUDA memcpy HtoD] API calls: 94.25% 158.04ms 30 5.2679ms 2.0740us 157.41ms cudaMalloc 2.21% 3.7138ms 10 371.38us 357.06us 376.51us cudaDeviceSynchronize 1.96% 3.2919ms 30 109.73us 6.7930us 276.61us cudaMemcpy 0.85% 1.4211ms 1 1.4211ms 1.4211ms 1.4211ms cuDeviceGetName 0.36% 595.89us 30 19.863us 2.5760us 75.126us cudaFree 0.17% 286.10us 1 286.10us 286.10us 286.10us cuDeviceTotalMem 0.13% 218.11us 97 2.2480us 296ns 86.428us cuDeviceGetAttribute 0.06% 107.84us 10 10.783us 8.6080us 23.725us cudaLaunchKernel 0.00% 6.1020us 1 6.1020us 6.1020us 6.1020us cuDeviceGetPCIBusId 0.00% 2.2910us 3 763ns 378ns 1.4840us cuDeviceGetCount 0.00% 1.4150us 2 707ns 318ns 1.0970us cuDeviceGet 0.00% 579ns 1 579ns 579ns 579ns cuDeviceGetUuid ``` ### Subtask2 這是以不同 filter type 來做 OpenCL 與 CUDA 的比較圖表  雖然看起來圖表上 CUDA 與 OpenCL 是有差距的,但是實際測其實上速度並沒有差,有時候測起來 CUDA 快,有時候 OpenCL 快 ### Subtask3 因爲同一張顯卡上,memory bandwidth bound等其他硬體限制都不變,並且這次跑得程式相對簡單不複雜,所以看不出什麼明顯差距 並且我其實並沒有特別使用 OpenCL 與 CUDA 的專門的 api function ,我兩個都只是做簡單的 memory copy 等基本操作,所以差距不大其實很合理
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up