diff --git a/doc/predef.qbk b/doc/predef.qbk index 6558d19..1f3eeab 100644 --- a/doc/predef.qbk +++ b/doc/predef.qbk @@ -143,6 +143,8 @@ macros of a particular prefix: * `BOOST_OS_` for the operating system we are compiling to. * `BOOST_PLAT_` for platforms on top of operating system or compilers. * `BOOST_ENDIAN_` for endianness of the os and architecture combination. +* `BOOST_HW_` for hardware specific features. +* `BOOST_HW_SIMD` for SIMD (Single Instruction Multiple Data) detection. [note The detected definitions are for the configuration one is targeting during the compile. In particular in a cross-compile this means the target @@ -223,6 +225,93 @@ detected. I.e. a definition equivalent to: Also for each aspect there is a macro defined with a descriptive name of what the detection is. +[heading The `BOOST_HW_SIMD_*` predefs] + +SIMD predefs depend on compiler options. For example, you will have to add the +option `-msse3` to clang or gcc to enable SSE3. SIMD predefs are also inclusive. +This means that if SSE3 is enabled, then every other extensions with a lower +version number will implicitly be enabled and detected. However, some extensions +are CPU specific, they may not be detected nor enabled when an upper version is +enabled. + +[note SSE(1) and SSE2 are automatically enabled by default when using x86-64 +architecture.] + +To check if any SIMD extension has been enabled, you can use: + +`` + #include + #include + + int main() + { +#if defined(BOOST_HW_SIMD_AVAILABLE) + std::cout << "SIMD detected!" << std::endl; +#endif + return 0; + } +`` + +When writing SIMD specific code, you may want to check if a particular extension +has been detected. To do so you have to use the right architecture predef and +compare it. Those predef are of the form `BOOST_HW_SIMD_"ARCH"` (where `"ARCH"` +is either `ARM`, `PPC`, or `X86`). For example, if you compile code for x86 +architecture, you will have to use `BOOST_HW_SIMD_x86`. Its value will be the +version number of the most recent SIMD extension detected for the architecture. + +To check if an extension has been enabled: + +`` + #include + #include + + int main() + { +#if defined(BOOST_HW_SIMD_X86_SSE3_AVAILABLE) + std::cout << "This is SSE3!" << std::endl; +#endif + return 0; + } +`` + +To "stricly" check the most recent detected extension: + +`` + #include + #include + + int main() + { +#if BOOST_HW_SIMD_X86 == BOOST_HW_SIMD_X86_SSE3 + std::cout << "This is SSE3 and this is the most recent enabled extension!" + << std::endl; +#endif + return 0; + } +`` + +Because of the version systems of predefs and of the inclusive property of SIMD +extensions macros, you can easily check for ranges of supported extensions: + +`` + #include + #include + + int main() + { +#if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2 &&\ + BOOST_HW_SIMD_X86 <= BOOST_HW_SIMD_X86_SSSE3 + std::cout << "This is SSE2, SSE3 and SSSE3!" << std::endl; +#endif + return 0; + } +`` + +[note Unlike gcc and clang, Visual Studio does not allow you to specify precisely +the SSE variants you want to use, the only detections that will take place are +SSE, SSE2, AVX and AVX2. For more informations, +see [@https://msdn.microsoft.com/en-us/library/b0084kay.aspx here]. + [heading The `*_EMULATED` macros] Predef definitions are guaranteed to be uniquely detected within one category.