https://wiki.gnuradio.org/index.php?title=VOLK_Guide&feed=atom&action=historyVOLK Guide - Revision history2024-03-28T18:11:53ZRevision history for this page on the wikiMediaWiki 1.39.5https://wiki.gnuradio.org/index.php?title=VOLK_Guide&diff=4875&oldid=prev777arc at 22:44, 12 March 20192019-03-12T22:44:00Z<p></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 22:44, 12 March 2019</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">[[Category:Usage Manual]]</ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Introduction ==</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Introduction ==</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<!-- diff cache key mediawiki:diff::1.12:old-4296:rev-4875 -->
</table>777archttps://wiki.gnuradio.org/index.php?title=VOLK_Guide&diff=4296&oldid=prev777arc: /* Calling VOLK kernels in Work() */2018-06-26T19:57:30Z<p><span dir="auto"><span class="autocomment">Calling VOLK kernels in Work()</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 19:57, 26 June 2018</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l83">Line 83:</td>
<td colspan="2" class="diff-lineno">Line 83:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>to ignore the concept of aligned versus unaligned. This looks like:</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>to ignore the concept of aligned versus unaligned. This looks like:</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"><syntaxhighlight lang="cpp"></ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> int</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> int</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> gr_some_block::work (int noutput_items,</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> gr_some_block::work (int noutput_items,</div></td></tr>
<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l97">Line 97:</td>
<td colspan="2" class="diff-lineno">Line 98:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> return noutput_items;</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> return noutput_items;</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> }</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> }</div></td></tr>
<tr><td colspan="2" class="diff-side-deleted"></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></syntaxhighlight></ins></div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Tuning VOLK Performance ==</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>== Tuning VOLK Performance ==</div></td></tr>
<!-- diff cache key mediawiki:diff::1.12:old-4232:rev-4296 -->
</table>777archttps://wiki.gnuradio.org/index.php?title=VOLK_Guide&diff=4232&oldid=prev777arc: /* Tuning VOLK Performance */2018-06-11T05:15:10Z<p><span dir="auto"><span class="autocomment">Tuning VOLK Performance</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 05:15, 11 June 2018</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l128">Line 128:</td>
<td colspan="2" class="diff-lineno">Line 128:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> volk_32fc_x2_multiply_32fc_u sse3</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> volk_32fc_x2_multiply_32fc_u sse3</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>'''Tip:''' <del style="font-weight: bold; text-decoration: none;">if </del>benchmarking GNU Radio blocks, it can be useful to have a</div></td><td class="diff-marker" data-marker="+"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>'''Tip:''' <ins style="font-weight: bold; text-decoration: none;">If </ins>benchmarking GNU Radio blocks, it can be useful to have a</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>volk_config file that sets all architectures to 'generic' as a way to</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>volk_config file that sets all architectures to 'generic' as a way to</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>test the vectorized versus non-vectorized implementations.</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>test the vectorized versus non-vectorized implementations.</div></td></tr>
<!-- diff cache key mediawiki:diff::1.12:old-4231:rev-4232 -->
</table>777archttps://wiki.gnuradio.org/index.php?title=VOLK_Guide&diff=4231&oldid=prev777arc: /* Calling VOLK kernels in Work() */2018-06-11T05:15:04Z<p><span dir="auto"><span class="autocomment">Calling VOLK kernels in Work()</span></span></p>
<table style="background-color: #fff; color: #202122;" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 05:15, 11 June 2018</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l82">Line 82:</td>
<td colspan="2" class="diff-lineno">Line 82:</td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>us. From the user-level view of VOLK, calling the dispatcher allows us</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>us. From the user-level view of VOLK, calling the dispatcher allows us</div></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>to ignore the concept of aligned versus unaligned. This looks like:</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>to ignore the concept of aligned versus unaligned. This looks like:</div></td></tr>
<tr><td class="diff-marker" data-marker="−"></td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div><del style="font-weight: bold; text-decoration: none;"></del></div></td><td colspan="2" class="diff-side-added"></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><br/></td></tr>
<tr><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> int</div></td><td class="diff-marker"></td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div> int</div></td></tr>
</table>777archttps://wiki.gnuradio.org/index.php?title=VOLK_Guide&diff=4230&oldid=prev777arc: Created page with "== Introduction == Note: Many blocks have already been converted to use VOLK in their calls, so they can also serve as examples. See the gr::blocks::complex_to_<type>.h files..."2018-06-11T05:14:52Z<p>Created page with "== Introduction == Note: Many blocks have already been converted to use VOLK in their calls, so they can also serve as examples. See the gr::blocks::complex_to_<type>.h files..."</p>
<p><b>New page</b></p><div>== Introduction ==<br />
<br />
Note: Many blocks have already been converted to use VOLK in their calls, so<br />
they can also serve as examples. See the<br />
gr::blocks::complex_to_<type>.h files for examples of various blocks<br />
that make use of VOLK.<br />
<br />
VOLK is the Vector-Optimized Library of Kernels. It is a library that<br />
contains kernels of hand-written SIMD code for different mathematical<br />
operations. Since each SIMD architecture can be greatly different and<br />
no compiler has yet come along to handle vectorization properly or<br />
highly efficiently, VOLK approaches the problem differently. For each<br />
architecture or platform that a developer wishes to vectorize for, a<br />
new proto-kernel is added to VOLK. At runtime, VOLK will select the<br />
correct proto-kernel. In this way, the users of VOLK call a kernel for<br />
performing the operation that is platform/architecture agnostic. This<br />
allows us to write portable SIMD code.<br />
<br />
VOLK kernels are always defined with a 'generic' proto-kernel, which<br />
is written in plain C. With the generic kernel, the kernel becomes<br />
portable to any platform. Kernels are then extended by adding<br />
proto-kernels for new platforms in which they are desired.<br />
<br />
A good example of a VOLK kernel with multiple proto-kernels defined is<br />
the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar<br />
multiplication of a vector of floating point numbers (each item in the<br />
vector is multiplied by the same value). This kernel has the following<br />
proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'neon'<br />
<br />
void volk_32f_s32f_multiply_32f_a_generic<br />
void volk_32f_s32f_multiply_32f_a_sse<br />
void volk_32f_s32f_multiply_32f_a_avx<br />
void volk_32f_s32f_multiply_32f_a_neon<br />
<br />
These proto-kernels means that on platforms with AVX support, VOLK can<br />
select this option or the SSE option, depending on which is faster. If<br />
all else fails, VOLK can fall back on the generic proto-kernel, which<br />
will always work.<br />
<br />
See [http://libvolk.org libvolk.org] for details on the VOLK naming scheme.<br />
<br />
== Setting and Using Memory Alignment Information ==<br />
<br />
For VOLK to work as best as possible, we want to use memory-aligned<br />
SIMD calls, which means we have to have some way of knowing and<br />
controlling the alignment of the buffers passed to gr_block's work<br />
function. We set the alignment requirement for SIMD aligned memory<br />
calls with:<br />
<br />
const int alignment_multiple =<br />
volk_get_alignment() / output_item_size;<br />
set_alignment(std::max(1,alignment_multiple));<br />
<br />
The VOLK function 'volk_get_alignment' provides the alignment of the<br />
the machine architecture. We then base the alignment on the number of<br />
output items required to maintain the alignment, so we divide the<br />
number of alignment bytes by the number of bytes in an output items<br />
(sizeof(float), sizeof(gr_complex), etc.). This value is then set per<br />
block with the 'set_alignment' function.<br />
<br />
Because the scheduler tries to optimize throughput, the number of<br />
items available per call to work will change and depends on the<br />
availability of the read and write buffers. This means that it<br />
sometimes cannot produce a buffer that is properly memory<br />
aligned. This is an inevitable consequence of the scheduler<br />
system. Instead of requiring alignment, the scheduler enforces the<br />
alignment as much as possible, and when a buffer becomes unaligned,<br />
the scheduler will work to correct it as much as possible. If a<br />
block's buffers are unaligned, then, the scheduler sets a flag to<br />
indicate as much so that the block can then decide what best to<br />
do. The next section discusses the use of the aligned/unaligned<br />
information in a gr_block's work function.<br />
<br />
== Calling VOLK kernels in Work() ==<br />
<br />
The buffers passed to work/general_work in a gr_block are not<br />
guaranteed to be aligned, but they will mostly be aligned whenever<br />
possible. When not aligned, the 'is_unaligned()' flag will be set so<br />
the scheduler knows to try to realign the buffers. We actually make<br />
calls to the VOLK dispatcher, which is mainly designed to check the<br />
buffer alignments and call the correct version of the kernel for<br />
us. From the user-level view of VOLK, calling the dispatcher allows us<br />
to ignore the concept of aligned versus unaligned. This looks like:<br />
<br />
<br />
int<br />
gr_some_block::work (int noutput_items,<br />
gr_vector_const_void_star &input_items,<br />
gr_vector_void_star &output_items)<br />
{<br />
const float *in = (const float *) input_items[0];<br />
float *out = (float *) output_items[0];<br />
<br />
// Call the dispatcher to check alignment and call the _a or _u<br />
// version of the kernel.<br />
volk_32f_something_32f(out, in, noutput_items);<br />
<br />
return noutput_items;<br />
}<br />
<br />
== Tuning VOLK Performance ==<br />
<br />
VOLK comes with a profiler that will build a config file for the best<br />
SIMD architecture for your processor. Run volk_profile that is<br />
installed into $PREFIX/bin. This program tests all known VOLK kernels<br />
for each architecture supported by the processor. When finished, it<br />
will write to $HOME/.volk/volk_config the best architecture for the<br />
VOLK function. This file is read when using a function to know the<br />
best version of the function to execute.<br />
<br />
=== Hand-Tuning Performance ===<br />
<br />
If you know a particular architecture works best for your processor,<br />
you can specify the particular architecture to use in the VOLK<br />
preferences file: $HOME/.volk/volk_config<br />
<br />
The file looks like:<br />
<br />
volk_<FUNCTION_NAME> <ARCHITECTURE><br />
<br />
Where the "FUNCTION_NAME" is the particular function that you want to<br />
over-ride the default value and "ARCHITECTURE" is the VOLK SIMD<br />
architecture to use (generic, sse, sse2, sse3, avx, etc.). For<br />
example, the following config file tells VOLK to use SSE3 for the<br />
aligned and unaligned versions of a function that multiplies two<br />
complex streams together.<br />
<br />
volk_32fc_x2_multiply_32fc_a sse3<br />
volk_32fc_x2_multiply_32fc_u sse3<br />
<br />
'''Tip:''' if benchmarking GNU Radio blocks, it can be useful to have a<br />
volk_config file that sets all architectures to 'generic' as a way to<br />
test the vectorized versus non-vectorized implementations.</div>777arc