|
||||
File indexing completed on 2025-01-18 09:48:05
0001 /* 0002 Copyright Charly Chevalier 2015 0003 Copyright Joel Falcou 2015 0004 Distributed under the Boost Software License, Version 1.0. 0005 (See accompanying file LICENSE_1_0.txt or copy at 0006 http://www.boost.org/LICENSE_1_0.txt) 0007 */ 0008 0009 #include <boost/predef/hardware/simd/x86.h> 0010 #include <boost/predef/hardware/simd/x86_amd.h> 0011 #include <boost/predef/hardware/simd/arm.h> 0012 #include <boost/predef/hardware/simd/ppc.h> 0013 0014 #ifndef BOOST_PREDEF_HARDWARE_SIMD_H 0015 #define BOOST_PREDEF_HARDWARE_SIMD_H 0016 0017 #include <boost/predef/version_number.h> 0018 0019 /* tag::reference[] 0020 = Using the `BOOST_HW_SIMD_*` predefs 0021 0022 SIMD predefs depend on compiler options. For example, you will have to add the 0023 option `-msse3` to clang or gcc to enable SSE3. SIMD predefs are also inclusive. 0024 This means that if SSE3 is enabled, then every other extensions with a lower 0025 version number will implicitly be enabled and detected. However, some extensions 0026 are CPU specific, they may not be detected nor enabled when an upper version is 0027 enabled. 0028 0029 NOTE: SSE(1) and SSE2 are automatically enabled by default when using x86-64 0030 architecture. 0031 0032 To check if any SIMD extension has been enabled, you can use: 0033 0034 [source] 0035 ---- 0036 #include <boost/predef/hardware/simd.h> 0037 #include <iostream> 0038 0039 int main() 0040 { 0041 #if defined(BOOST_HW_SIMD_AVAILABLE) 0042 std::cout << "SIMD detected!" << std::endl; 0043 #endif 0044 return 0; 0045 } 0046 ---- 0047 0048 When writing SIMD specific code, you may want to check if a particular extension 0049 has been detected. To do so you have to use the right architecture predef and 0050 compare it. Those predef are of the form `BOOST_HW_SIMD_"ARCH"` (where `"ARCH"` 0051 is either `ARM`, `PPC`, or `X86`). For example, if you compile code for x86 0052 architecture, you will have to use `BOOST_HW_SIMD_X86`. Its value will be the 0053 version number of the most recent SIMD extension detected for the architecture. 0054 0055 To check if an extension has been enabled: 0056 0057 [source] 0058 ---- 0059 #include <boost/predef/hardware/simd.h> 0060 #include <iostream> 0061 0062 int main() 0063 { 0064 #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE3_VERSION 0065 std::cout << "This is SSE3!" << std::endl; 0066 #endif 0067 return 0; 0068 } 0069 ---- 0070 0071 NOTE: The *_VERSION* defines that map version number to actual real 0072 identifiers. This way it is easier to write comparisons without messing up with 0073 version numbers. 0074 0075 To *"strictly"* check the most recent detected extension: 0076 0077 [source] 0078 ---- 0079 #include <boost/predef/hardware/simd.h> 0080 #include <iostream> 0081 0082 int main() 0083 { 0084 #if BOOST_HW_SIMD_X86 == BOOST_HW_SIMD_X86_SSE3_VERSION 0085 std::cout << "This is SSE3 and this is the most recent enabled extension!" 0086 << std::endl; 0087 #endif 0088 return 0; 0089 } 0090 ---- 0091 0092 Because of the version systems of predefs and of the inclusive property of SIMD 0093 extensions macros, you can easily check for ranges of supported extensions: 0094 0095 [source] 0096 ---- 0097 #include <boost/predef/hardware/simd.h> 0098 #include <iostream> 0099 0100 int main() 0101 { 0102 #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2_VERSION &&\ 0103 BOOST_HW_SIMD_X86 <= BOOST_HW_SIMD_X86_SSSE3_VERSION 0104 std::cout << "This is SSE2, SSE3 and SSSE3!" << std::endl; 0105 #endif 0106 return 0; 0107 } 0108 ---- 0109 0110 NOTE: Unlike gcc and clang, Visual Studio does not allow you to specify precisely 0111 the SSE variants you want to use, the only detections that will take place are 0112 SSE, SSE2, AVX and AVX2. For more informations, 0113 see [@https://msdn.microsoft.com/en-us/library/b0084kay.aspx here]. 0114 0115 0116 */ // end::reference[] 0117 0118 // We check if SIMD extension of multiples architectures have been detected, 0119 // if yes, then this is an error! 0120 // 0121 // NOTE: _X86_AMD implies _X86, so there is no need to check for it here! 0122 // 0123 #if defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_PPC_AVAILABLE) ||\ 0124 defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) ||\ 0125 defined(BOOST_HW_SIMD_PPC_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) 0126 # error "Multiple SIMD architectures detected, this cannot happen!" 0127 #endif 0128 0129 #if defined(BOOST_HW_SIMD_X86_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) 0130 // If both standard _X86 and _X86_AMD are available, 0131 // then take the biggest version of the two! 0132 # if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_AMD 0133 # define BOOST_HW_SIMD BOOST_HW_SIMD_X86 0134 # else 0135 # define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD 0136 # endif 0137 #endif 0138 0139 #if !defined(BOOST_HW_SIMD) 0140 // At this point, only one of these two is defined 0141 # if defined(BOOST_HW_SIMD_X86_AVAILABLE) 0142 # define BOOST_HW_SIMD BOOST_HW_SIMD_X86 0143 # endif 0144 # if defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE) 0145 # define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD 0146 # endif 0147 #endif 0148 0149 #if defined(BOOST_HW_SIMD_ARM_AVAILABLE) 0150 # define BOOST_HW_SIMD BOOST_HW_SIMD_ARM 0151 #endif 0152 0153 #if defined(BOOST_HW_SIMD_PPC_AVAILABLE) 0154 # define BOOST_HW_SIMD BOOST_HW_SIMD_PPC 0155 #endif 0156 0157 #if defined(BOOST_HW_SIMD) 0158 # define BOOST_HW_SIMD_AVAILABLE 0159 #else 0160 # define BOOST_HW_SIMD BOOST_VERSION_NUMBER_NOT_AVAILABLE 0161 #endif 0162 0163 #define BOOST_HW_SIMD_NAME "Hardware SIMD" 0164 0165 #endif 0166 0167 #include <boost/predef/detail/test.h> 0168 BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD, BOOST_HW_SIMD_NAME)
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |