<p>In this post, we will be looking at benchmarks of the below listed ArrayFire image processing functions on an ARM device.</p>
<ul>
<li>Erosion/Dilation<br /></li>
<li>Median filter<br /></li>
<li>Resize<br /></li>
<li>Histogram<br /></li>
<li>Bilateral filter<br /></li>
<li>Convolution</li>
</ul>
<p>We pitched the brand new compute 3.2 GPU on NVIDIA Jetson TK1 against a mobile NVIDIA GPU. The closest match to the GPU(from here on referred as TK1) on Jetson board we have in our mobile card deck is a NVIDIA GT 650M. Though it has twice as many cores as a TK1, there are many other parameters that influence the performance of the CUDA kernels. Below given is the spec comparison of both the GPUs for your reference. The properties that have more critical effect on the performance of the functions are listed below.</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Property Name / Device Name</th>
<th style="text-align: left;">Jetson TK1 GK20A</th>
<th style="text-align: left;">GT 650M</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Compute</td>
<td style="text-align: left;">3.2</td>
<td style="text-align: left;">3.0</td>
</tr>
<tr class="even">
<td style="text-align: left;">Number of multiprocessors</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">2</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Cores</td>
<td style="text-align: left;">192</td>
<td style="text-align: left;">384</td>
</tr>
<tr class="even">
<td style="text-align: left;">Base clock rate</td>
<td style="text-align: left;">852 MHz</td>
<td style="text-align: left;">950 MHz</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Total global memory</td>
<td style="text-align: left;">1746 MB</td>
<td style="text-align: left;">2048 MB</td>
</tr>
<tr class="even">
<td style="text-align: left;">Total shared memory per block</td>
<td style="text-align: left;">48 KB</td>
<td style="text-align: left;">48 KB</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Total constant memory</td>
<td style="text-align: left;">64 KB</td>
<td style="text-align: left;">64KB</td>
</tr>
<tr class="even">
<td style="text-align: left;">Memory clock rate</td>
<td style="text-align: left;">924 MHz</td>
<td style="text-align: left;">900 MHz</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Memory bus width</td>
<td style="text-align: left;">64-bit</td>
<td style="text-align: left;">128-bit</td>
</tr>
<tr class="even">
<td style="text-align: left;">Total registers per block</td>
<td style="text-align: left;">32768</td>
<td style="text-align: left;">65536</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Warp size</td>
<td style="text-align: left;">32</td>
<td style="text-align: left;">32</td>
</tr>
</tbody>
</table>
<h3 id="benchmarks">Benchmarks</h3>
Images with the below resolutions are used for benchmarks. 
<ul>
<li>480p (720x480)</li>
<li>720p and 1080p HD</li>
<li>4K and 8K UHD</li>
</ul>
Note that the vertical axis(Frames per second) in all the plots is on log scale. The higher the value along vertical axis, the better the run times are for that function on that specific device.
<h4 id="erosiondilation">Erosion/Dilation</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/erode.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/erode.png" alt="erode" width="640" height="480" class="alignnone size-full wp-image-5805" /></a>
<p>3x3 mask was used to benchmark <code>erode</code> function. Dilate results will be similar to erode as they use the same algorithm with different local neighborhood operator.</p>
<h4 id="median-filter">Median filter</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/medfilt.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/medfilt.png" alt="medfilt" width="640" height="480" class="alignnone size-medium wp-image-5801" /></a>
<p>3x3 mask was used to benchmark <code>medfilt</code> function as well.</p>
<h4 id="resize">Resize</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/resize.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/resize.png" alt="resize" width="640" height="480" class="alignnone size-medium wp-image-5800" /></a>
<p>We benchmarked <code>resize</code> for halving the image size.</p>
<h4 id="histogram">Histogram</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/hist.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/hist.png" alt="hist" width="640" height="480" class="alignnone size-medium wp-image-5802" /></a>
<p>Standard 256 bin <code>histogram</code></p>
<h4 id="bilateral-filter">Bilateral filter</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/bilateral.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/bilateral.png" alt="bilateral" width="640" height="480" class="alignnone size-medium wp-image-5804" /></a>
<p>We used 3.5(7x7 window) spatial variance and 50 chromatic variance to benchmark <code>bilateral</code> function. Note that for the 4320p resolution, we got one frame per second processing speed.</p>
<h4 id="convolution">Convolution</h4>
<a href="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/conv.png"><img src="http://sandbox.arrayfire.com/wp-content/uploads/2014/06/conv.png" alt="conv" width="640" height="480" class="alignnone size-medium wp-image-5803" /></a>
<p>5x5 blur kernel was used to benchmark <code>convolve</code> function.</p>

<h3>Conclusion</h3>
<code>erode</code>, <code>resize</code> and <code>conv</code> run in real time for 480p, and all HD resolutions 720p, 1080p and 4K except 