.. _fmv: Function Multi-Versioning ######################### In this tutorial, we will use :abbr:`FMV (Function Multi-Versioning)` on general code and on :abbr:`FFT (Fast Fourier Transform)` library code (FFTW). Upon completing the tutorial, you will be able to use this technology on your code and use the libraries to deploy architecture-based optimizations to your application code. .. contents:: :local: :depth: 1 Description *********** CPU architectures often gain interesting new instructions as they evolve but application developers find it difficult to take advantage of those instructions. The reluctance to lose backward-compatibility is one of the main roadblocks slowing developers from using advancements in newer computing architectures. FMV, which first appeared in `GCC`_ 4.8, is a way to have multiple implementations of a function, each using different architecture-specialized instruction-set extensions. GCC 6 introduces changes to FMV to make it even easier to bring architecture-based optimizations to the application code. Install and configure a |CL| host on bare metal *********************************************** First, follow our guide to :ref:`bare-metal-install-desktop`. Once the bare metal installation and initial configuration are complete, add the :command:`desktop-dev` bundle to the system. :command:`desktop-dev` contains the necessary development tools like GCC and Perl\*. #. To install the bundles, run the following command in the :file:`$HOME` directory: .. code-block:: bash sudo swupd bundle-add desktop-dev Detect loop vectorization candidates ************************************ Now, we need to detect the loop vectorization candidates to be cloned for multiple platforms with FMV. As an example, we will use the following simple C code: .. code-block:: c :linenos: #include #include #include #define MAX 1000000 int a[256], b[256], c[256]; void foo(){ int i,x; for (x=0; x log #. To generate the patch files, execute: .. code-block:: bash perl ./make-fmv-patch/make-fmv-patch.pl log . #. The :file:`make-fmv-patch.pl` script takes two arguments: `` and ``. Replace `` and `` with the proper values and execute: .. code-block:: bash perl make-fmv-patch.pl The command generates the following :file:`example.c.patch` patch: .. code-block:: console --- ./example.c 2017-09-27 16:05:42.279505430 +0000 +++ ./example.c~ 2017-09-27 16:19:11.691544026 +0000 @@ -5,6 +5,7 @@ int a[256], b[256], c[256]; +__attribute__((target_clones("avx2","arch=atom","default"))) void foo(){ int i,x; for (x=0; x #include #include #define MAX 1000000 int a[256], b[256], c[256]; __attribute__((target_clones("avx2","arch=atom","default"))) void foo(){ int i,x; for (x=0; x y) ? x : y; } +__attribute__((target_clones("avx2","arch=atom","default"))) static double aerror(C *a, C *b, int n) { if (n > 0) { @@ -111,6 +112,7 @@ } /* make array hermitian */ +__attribute__((target_clones("avx2","arch=atom","default"))) void mkhermitian(C *A, int rank, const bench_iodim *dim, int stride) { if (rank == 0) @@ -148,6 +150,7 @@ } /* C = A + B */ +__attribute__((target_clones("avx2","arch=atom","default"))) void aadd(C *c, C *a, C *b, int n) { int i; @@ -159,6 +162,7 @@ } /* C = A - B */ +__attribute__((target_clones("avx2","arch=atom","default"))) void asub(C *c, C *a, C *b, int n) { int i; @@ -170,6 +174,7 @@ } /* B = rotate left A (complex) */ +__attribute__((target_clones("avx2","arch=atom","default"))) void arol(C *b, C *a, int n, int nb, int na) { int i, ib, ia; @@ -192,6 +197,7 @@ } } With these patches, we can select where to apply the FMV technology, which makes it even easier to bring architecture-based optimizations to application code. **Congratulations!** You have successfully installed an FMV development environment on |CL|. Furthermore, you used cutting edge compiler technology to improve the performance of your application based on IntelĀ® architecture and profiling of the specific execution of your application. *Intel and the Intel logo are trademarks of Intel Corporation or its subsidiaries.* .. _GCC: https://gcc.gnu.org .. _make-fmv-patch: https://github.com/clearlinux/make-fmv-patch