Changes

Jump to: navigation, search

TudyBert

8,435 bytes added, 14:29, 19 April 2013
Assignment 3
Here's the flat profile for 50 runs of enlarging a 512px x 512px image 4 times:
 
 
% cumulative self self total
1.07 2.78 0.03 4194304 0.00 0.00 Image::getPixelVal(int, int)
The code for enlarge image:
The code for enlargeImage():
void Image::enlargeImage(int value, Image& oldImage)
{
int rows, cols, gray;
int pixel;
}
oldImage = tempImage;
  The four for loops look like they could be parallelized since they just serve as counters. From the flat file, it seems that the majority of the time is spent in the overloaded operator=() method. The code for this is: <div> N <span style='color:#808030; '>=</span> oldImage<span style='color:#808030; '>.</span>N<span style='color:#800080; '>;</span> M <span style='color:#808030; '>=</span> oldImage<span style='color:#808030; '>.</span>M<span style='color:#800080; '>;</span> Q <span style='color:#808030; '>=</span> oldImage<span style='color:#808030; '>.</span>Q<span style='color:#800080; '>;</span> <span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>dim1 <span style='color:#808030; '>!</span><span style='color:#808030; '>=</span> <span style='color:#7d0045; '>NULL</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span> <span style='color:#800000; font-weight:bold; '>delete</span><span style='color:#808030; '>[</span><span style='color:#808030; '>]</span> dim1<span style='color:#800080; '>;</span> <span style='color:#800080; '>}</span> pixelVal <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> <span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>*</span> <span style='color:#808030; '>[</span>N<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span> dim1 <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> <span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>[</span>N<span style='color:#808030; '>*</span>M<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span> <span style='color:#800000; font-weight:bold; '>for</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span> i <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> i <span style='color:#808030; '>&lt;</span> N<span style='color:#800080; '>;</span> i<span style='color:#808030; '>+</span><span style='color:#808030; '>+</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span> pixelVal<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>new</span> <span style='color:#800000; font-weight:bold; '>int</span> <span style='color:#808030; '>[</span>M<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span> <span style='color:#800000; font-weight:bold; '>for</span><span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span> j <span style='color:#808030; '>=</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span> j <span style='color:#808030; '>&lt;</span> M<span style='color:#800080; '>;</span> j<span style='color:#808030; '>+</span><span style='color:#808030; '>+</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span> pixelVal<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>[</span>j<span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> oldImage<span style='color:#808030; '>.</span>pixelVal<span style='color:#808030; '>[</span>i<span style='color:#808030; '>]</span><span style='color:#808030; '>[</span>j<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span> dim1<span style='color:#808030; '>[</span>i<span style='color:#808030; '>*</span>N <span style='color:#808030; '>+</span> j<span style='color:#808030; '>]</span> <span style='color:#808030; '>=</span> oldImage<span style='color:#808030; '>.</span>dim1<span style='color:#808030; '>[</span>i<span style='color:#808030; '>*</span>N <span style='color:#808030; '>+</span> j<span style='color:#808030; '>]</span><span style='color:#800080; '>;</span> <span style='color:#800080; '>}</span> <span style='color:#800080; '>}</span></div>   The chunk of the processing is wasted on copying the two arrays over from one image to another. If I have time I might look into parallelizing this as well. It would be interesting to see if the speed of the GPU can overcome the overhead of copying to and from the device. === Assignment 2 ===For Assignment 2 I simply put the four for loops into a kernel and replaced the outermost loop with thread indices. I made a helper method that set up memory on the device and launched the kernel with a 1 dimension array of blocks each containing 1 thread. I launched as many blocks of 1 thread as there were rows in the image file. I figured this was the quickest way to get this method parallelized. Unfortunately I hit a wall with my data sizes. The CPU version of the enlarge image method fails when run for more than 50 loops. The error thrown is a Visual Studio debugging error so I'm think VS isn't too happy with having the CPU hogged for so long. As a result I've had to extrapolate times for larger loops by assuming a linear increase in time taken.    Here's the code for newly parallelized method:  int idx = blockIdx.x * blockDim.x + threadIdx.x; int enlargeRow, enlargeCol; __shared__ int pixel; for(int j = 0; j < nj; j++) { pixel = work[idx * nj + j]; enlargeRow = idx * factor; enlargeCol = j * factor; for(int c = enlargeRow; c < (enlargeRow + factor); c++) { for(int d = enlargeCol; d < (enlargeCol + factor); d++) { result[d + c * blockDim.x * gridDim.x * factor] = pixel; } } } While I did see a decrease in the time taken to run 50 loops, the decrease wasn't as significant as I had hoped. Obviously this kernel isn't optimized so I'm looking forward to some more impressive results as I update the code. 
=== Assignment 3 ===
After making sure memory access is coalesced and replacing the second counter loop with threads from a 2 dimensional block of 2 dimensional threads, I've achieved significant speed ups in the program. All it took was launching the kernel with an optimized 2D array of blocks each containing a 2D array of threads. For assignment 2 I had a grid with 1 thread for each column in the image. That meant each thread was running 3 nested for loops to do the necessary calculations for enlarging. Figuring out the math for calculating the correct index in the arrays proved to be tricky. Although I knew exactly what to do in concept, the two extra nested for loops threw me off. For a long time the image was being enlarged correctly but the physical dimensions of the image weren't increasing. Once I had that figured out the image was enlarging but not to the new dimensions. After some tracing and trial and error I managed to find the right formula to calculate the indices.
 
 
Here's the final, optimized enlarge method:
 
<span style='color:#7f0055; font-weight:bold; '>int</span> jdx = blockIdx.x * blockDim.x + threadIdx.x;
 
<span style='color:#7f0055; font-weight:bold; '>int</span> idx = blockIdx.y * blockDim.y + threadIdx.y;
 
<span style='color:#7f0055; font-weight:bold; '>int</span> k = idx + jdx * blockDim.x * gridDim.x;
 
<span style='color:#7f0055; font-weight:bold; '>int</span> enlargeRow, enlargeCol;
 
__shared__ <span style='color:#7f0055; font-weight:bold; '>int</span> pixel;
 
pixel = work[k];
 
enlargeRow = idx * factor;
 
enlargeCol = jdx * factor;
 
__syncthreads();
 
<span style='color:#7f0055; font-weight:bold; '>for</span>(<span style='color:#7f0055; font-weight:bold; '>int</span> c = enlargeRow; c &lt; (enlargeRow + factor); c++)
 
{
 
<span style='color:#7f0055; font-weight:bold; '>for</span>(<span style='color:#7f0055; font-weight:bold; '>int</span> d = enlargeCol; d &lt; (enlargeCol + factor); d++)
 
{
 
result[c + d * blockDim.x * gridDim.x * factor] = pixel;
 
__syncthreads();
 
}
 
}
 
 
I enjoyed parallelizing this program and really wish I could have figured out the CERN project. To make myself feel better I also parallelized the rotate image method.
 
 
 
I was going to paste the code snippet here but I'm getting frustrated with the formatting. Why is it so difficult to nicely format code on a Wiki? [http://pastebin.com/ZZV9KRJN Here] it is.
1
edit

Navigation menu