Brian Silverman | 44c68b1 | 2018-08-04 23:56:44 -0700 | [diff] [blame^] | 1 | SIMD predefs depend on compiler options. For example, you will have to add the |
| 2 | option `-msse3` to clang or gcc to enable SSE3. SIMD predefs are also inclusive. |
| 3 | This means that if SSE3 is enabled, then every other extensions with a lower |
| 4 | version number will implicitly be enabled and detected. However, some extensions |
| 5 | are CPU specific, they may not be detected nor enabled when an upper version is |
| 6 | enabled. |
| 7 | |
| 8 | [note SSE(1) and SSE2 are automatically enabled by default when using x86-64 |
| 9 | architecture.] |
| 10 | |
| 11 | To check if any SIMD extension has been enabled, you can use: |
| 12 | |
| 13 | `` |
| 14 | #include <boost/predef/hardware/simd.h> |
| 15 | #include <iostream> |
| 16 | |
| 17 | int main() |
| 18 | { |
| 19 | #if defined(BOOST_HW_SIMD_AVAILABLE) |
| 20 | std::cout << "SIMD detected!" << std::endl; |
| 21 | #endif |
| 22 | return 0; |
| 23 | } |
| 24 | `` |
| 25 | |
| 26 | When writing SIMD specific code, you may want to check if a particular extension |
| 27 | has been detected. To do so you have to use the right architecture predef and |
| 28 | compare it. Those predef are of the form `BOOST_HW_SIMD_"ARCH"` (where `"ARCH"` |
| 29 | is either `ARM`, `PPC`, or `X86`). For example, if you compile code for x86 |
| 30 | architecture, you will have to use `BOOST_HW_SIMD_X86`. Its value will be the |
| 31 | version number of the most recent SIMD extension detected for the architecture. |
| 32 | |
| 33 | To check if an extension has been enabled: |
| 34 | |
| 35 | `` |
| 36 | #include <boost/predef/hardware/simd.h> |
| 37 | #include <iostream> |
| 38 | |
| 39 | int main() |
| 40 | { |
| 41 | #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE3_VERSION |
| 42 | std::cout << "This is SSE3!" << std::endl; |
| 43 | #endif |
| 44 | return 0; |
| 45 | } |
| 46 | `` |
| 47 | |
| 48 | [note The *_VERSION* defines that map version number to actual real |
| 49 | identifiers. This way it is easier to write comparisons without messing up with |
| 50 | version numbers.] |
| 51 | |
| 52 | To *"stricly"* check the most recent detected extension: |
| 53 | |
| 54 | `` |
| 55 | #include <boost/predef/hardware/simd.h> |
| 56 | #include <iostream> |
| 57 | |
| 58 | int main() |
| 59 | { |
| 60 | #if BOOST_HW_SIMD_X86 == BOOST_HW_SIMD_X86_SSE3_VERSION |
| 61 | std::cout << "This is SSE3 and this is the most recent enabled extension!" |
| 62 | << std::endl; |
| 63 | #endif |
| 64 | return 0; |
| 65 | } |
| 66 | `` |
| 67 | |
| 68 | Because of the version systems of predefs and of the inclusive property of SIMD |
| 69 | extensions macros, you can easily check for ranges of supported extensions: |
| 70 | |
| 71 | `` |
| 72 | #include <boost/predef/hardware/simd.h> |
| 73 | #include <iostream> |
| 74 | |
| 75 | int main() |
| 76 | { |
| 77 | #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2_VERSION &&\ |
| 78 | BOOST_HW_SIMD_X86 <= BOOST_HW_SIMD_X86_SSSE3_VERSION |
| 79 | std::cout << "This is SSE2, SSE3 and SSSE3!" << std::endl; |
| 80 | #endif |
| 81 | return 0; |
| 82 | } |
| 83 | `` |
| 84 | |
| 85 | [note Unlike gcc and clang, Visual Studio does not allow you to specify precisely |
| 86 | the SSE variants you want to use, the only detections that will take place are |
| 87 | SSE, SSE2, AVX and AVX2. For more informations, |
| 88 | see [@https://msdn.microsoft.com/en-us/library/b0084kay.aspx here].] |
| 89 | |