309 Commits

Author SHA1 Message Date
Andrey Semashev 27080fe7d8 Correct static assert message in from_chars_x86. 2026-07-14 00:37:42 +03:00
Andrey Semashev 16da2030cc Fix a typo in a comment. 2026-01-22 16:45:09 +03:00
Andrey Semashev 0b38910c1d Fix gcc version check for diagnostic pop to match diagnostic push. 2026-01-22 16:45:02 +03:00
Peter Dimov 884c050576 Add boost::uuid::invalid_uuid exception class 2026-01-14 19:53:21 +02:00
Peter Dimov 0b6a9ade9a Respect the OutputIterator value_type in to_chars 2026-01-13 17:47:01 +02:00
Andrey Semashev ba77fe2781 Added SSE2 and SSSE3 SIMD implementations of from_chars.
This adds SSE2 and SSSE3 code paths to from_chars_x86.hpp. The performance
effect on Intel Golden Cove (Core i7-12700K), gcc 13.3, in millions of
successful from_chars() calls per second:

Char     | Generic | SSE2            | SSSE3           | SSE4.1          | AVX2            | AVX512v1
=========+=========+=================+=================+=================+=================+================
char     |  40.475 | 327.791 (8.10x) | 465.857 (11.5x) | 555.346 (13.7x) | 504.648 (12.5x) | 539.700 (13.3x)
char16_t |  38.757 | 292.048 (7.54x) | 401.117 (10.3x) | 478.574 (12.3x) | 426.188 (11.0x) | 416.205 (10.7x)
char32_t |  50.200 | 150.900 (3.01x) | 204.588 (4.08x) | 389.882 (7.77x) | 359.591 (7.16x) | 349.663 (6.97x)

In addition, the workarounds to avoid (v)pblendvb instructions have been
extended to Intel Haswell and Broadwell, as these microarchitectures have
poor performance with these instructions (including the SSE4.1 pblendvb).

Two new experimental control macros added: BOOST_UUID_FROM_CHARS_X86_SLOW_PBLENDVB
and BOOST_UUID_FROM_CHARS_X86_USE_PBLENDVB. The former indicates that
(v)pblendvb instructions are slow and should be avoided on the target
microarchitectures. The latter indicates that (v)pblendvb should be used
by the implementation. The latter macro is derived from the former and
takes precedence. As before, these macros can be used for experimenting
and fine tuning performance for specific target CPUs. By default,
BOOST_UUID_FROM_CHARS_X86_SLOW_PBLENDVB is defined for Haswell/Broadwell
or if AVX is detected.

Lastly, made selection between blend-based and shuffle-based character
code conversion in various places unified, controlled by a single
internal macro BOOST_UUID_DETAIL_FROM_CHARS_X86_USE_BLENDS.
2026-01-10 12:15:59 +03:00
Andrey Semashev 97dc5c35ba Added SSE2 SIMD implementation of to_chars.
This adds SSE2 code paths to to_chars_x86.hpp. The performance effect on
Intel Golden Cove (Core i7-12700K), gcc 13.3, in millions of to_chars() calls
per second with a 16-byte aligned output buffer:

Char     | Generic | SSE2            | SSE4.1           | AVX2             | AVX10.1
=========+=========+=================+==================+==================+=================
char     | 202.314 | 564.857 (2.79x) | 1194.772 (5.91x) | 1192.094 (5.89x) | 1191.838 (5.89x)
char16_t | 188.532 | 457.281 (2.43x) |  795.798 (4.22x) |  935.016 (4.96x) |  938.368 (4.98x)
char32_t | 193.151 | 345.612 (1.79x) |  489.620 (2.53x) |  688.829 (3.57x) |  689.617 (3.57x)

Here, Generic column was generated with BOOST_UUID_NO_SIMD defined and
SSE2 with -march=x86-64. SSE2 support can be useful in cases when users
need to be compatible with the base x86-64 ISA.
2026-01-10 12:15:59 +03:00
Andrey Semashev d53a476a77 Silence -Wstrict-aliasing warning in simd_vector.hpp. 2026-01-10 12:15:59 +03:00
Andrey Semashev 39946fb660 Fix -Wconversion warning in from_chars_x86.hpp. 2026-01-10 12:15:59 +03:00
Peter Dimov 8febad40ed Make string_generator support string-like types like uuid_from_string does 2026-01-09 21:44:26 +02:00
Andrey Semashev 22e7ba81a9 Removed unnecessary includes and warning suppression in uuid_io.hpp. 2026-01-09 14:35:03 +03:00
Peter Dimov 095a47fe04 Change the type of pos to std::ptrdiff_t to avoid casts 2026-01-08 22:57:00 +02:00
Peter Dimov ea77c34803 Make uuid_from_string constexpr 2026-01-08 18:52:56 +02:00
Peter Dimov d493f92dcd Add uuid_from_string 2026-01-08 16:59:10 +02:00
Andrey Semashev 663ffa1287 Make cast formatting consistent with the rest of the file. 2026-01-07 20:13:18 +03:00
Andrey Semashev 286b66b385 Fix -Wsign-conversion warning with gcc 13.3. 2026-01-07 20:08:43 +03:00
Peter Dimov 347258c6c8 When BOOST_UUID_NO_SIMD is defined, undef all other SIMD macros, because otherwise the configuration becomes inconsistent 2026-01-06 16:32:16 +02:00
Peter Dimov e567490082 Fix BOOST_UUID_REPORT_IMPLEMENTATION messages 2026-01-06 16:26:35 +02:00
Peter Dimov 2b387b4638 Avoid -Wsign-conversion warnings in from_chars_x86.hpp 2026-01-05 17:56:10 +02:00
Peter Dimov f852d61bee Avoid -Wsign-conversion warnings in to_chars_x86.hpp 2026-01-05 17:44:32 +02:00
Peter Dimov 0b86240e0d Avoid -Wconversion warning in time_generator_v6.hpp under GCC 5 and below 2026-01-05 16:54:55 +02:00
Peter Dimov eabd000a54 Avoid -Wconversion, -Wsign-conversion warnings in detail/basic_name_generator.hpp under GCC 9 and below 2026-01-05 16:54:55 +02:00
Peter Dimov 520b3632f3 Avoid -Wsign-conversion warning in detail/basic_name_generator.hpp when wchar_t is int32_t 2026-01-05 16:54:55 +02:00
Peter Dimov 09a6a81b6b Avoid -Wconversion warning in detail/md5.hpp 2026-01-05 16:54:55 +02:00
Peter Dimov 2ce9519afc Avoid -Wsign-conversion warning in detail/sha1.hpp 2026-01-05 16:54:54 +02:00
Peter Dimov fd167bba0d Avoid -Wsign-conversion warning in time_generator_v1.hpp 2026-01-05 16:54:54 +02:00
Peter Dimov a835ddff90 Avoid -Wsign-conversion warning in time_generator_v7.hpp 2026-01-05 16:54:54 +02:00
Peter Dimov db92124922 Reorder includes 2026-01-05 16:02:11 +02:00
Andrey Semashev 0e23b235fc Use load/store helpers from endian.hpp in to/from_chars_x86.hpp.
The load/store helpers use memcpy internally, which is a more correct
way to load and store integers from/to unaligned memory and with
potential type punning. In particular, it should silence UBSAN errors
about unaligned memory accesses in SIMD algorithms.
2026-01-05 14:13:10 +03:00
Andrey Semashev 3698f8df2c Added a missing include. 2026-01-05 14:13:10 +03:00
Andrey Semashev 9dde4978fd Use memcpy/memset/memcmp functions from cstring.hpp in endian.hpp.
This benefits integer reads/writes from using compiler intrinsics,
when possible.
2026-01-05 14:13:10 +03:00
Andrey Semashev d358c39a67 Use __builtin_memcpy/memcmp in cstring.hpp.
The builtins are sometimes more strongly optimized than the libc function
calls. They also don't need the <cstring> include.

Added unqualified memcpy function that simply calls either the builtin or
the libc function. This function is intended to be a drop-in replacement
for the libc memcpy calls, where constexpr friendliness is not important.
It is still marked as constexpr to allow mentioning them in other constexpr
functions. To avoid early checks whether its body can be evaluated in the
context of a constant expression, it is defined as a dummy template.

Marked all functions as noexcept.
2026-01-05 14:13:10 +03:00
Andrey Semashev b7535347ec Allow users to enable 512-bit vectors in to_chars_x86.hpp.
Following from_chars_x86.hpp, allow users to explicitly enable 512-bit
vectors in to_chars by defining BOOST_UUID_TO_FROM_CHARS_X86_USE_ZMM.
This is primarily to allow for experimenting and tuning performance on
newer CPU microarchitectures.
2026-01-05 14:13:10 +03:00
Andrey Semashev 3920cc584c Added x86 SIMD implementation of from_chars.
This adds SSE4.1, AVX2, AVX-512v1 and AVX10.1 implementations of the
from_chars algorithm. The generic implementation is moved to its own
header and constexpr is relaxed to only enabled when is_constant_evaluated
is supported.

The performance effect on Intel Golden Cove (Core i7-12700K), gcc 13.3,
in millions of successful from_chars() calls per second:

Char     | Generic | SSE4.1          | AVX2            | AVX512v1        | AVX10.1
=========+=========+=================+=================+=================+================
char     |  38.571 | 560.645 (14.5x) | 501.505 (13.0x) | 540.038 (14.0x) | 480.778 (12.5x)
char16_t |  37.998 | 479.308 (12.6x) | 425.728 (11.2x) | 416.379 (11.0x) | 392.326 (10.3x)
char32_t |  50.327 | 391.313 (7.78x) | 359.312 (7.14x) | 349.849 (6.95x) | 333.979 (6.64x)

The AVX2 version is slightly slower than SSE4.1 because on Intel
microarchitectures the VEX-coded vpblendvb instruction is slower than
the legacy SSE4.1 pblendvb. The code contains workarounds for this, which
have slight performance overhead compared to SSE4.1 version, but are still
faster than using vpblendvb. Alternatively, the performance could be
improved by using asm blocks to force using pblendvb in AVX2 code, but this
may potentially cause SSE/AVX transition penalties if the target vector
register happens to have "dirty" upper bits. There's no way to ensure this
doesn't happen, so this is not implemented. AVX512v1 claws back some
performance and uses less instructions (i.e. smaller code size).

The AVX10.1 version is slower as it uses vpermi2b instruction from AVX512_VBMI,
which is relatively slow on Intel. It allows for reducing the number of
instructions even further and the number of vector constants as well. The
instruction is faster on AMD Zen 4 and should offer better performance compared
to AVX512v1 code path, although it wasn't tested. This code path is disabled
by default, unless BOOST_UUID_FROM_CHARS_X86_USE_VPERMI2B is defined, which
can be used to test and tune performance on AMD and newer Intel CPU
microarchitectures. Thus, by default, AVX10.1 performance should be roughly
equivalent to AVX512v1, barring compiler (mis)optimizations.

The unsuccessful parsing case depends on where the error happens, as the
generic version may terminate sooner if the error is detected at the
beginning of the input string, while the SIMD version performs roughly
the same amount of work but faster. Here are some examples for 8-bit
character types (for larger types the numbers are more or less comparable):

Error              | Generic  | SSE4.1          | AVX2            | AVX512v1        | AVX10.1
===================+==========+=================+=================+=================+================
EOI at 35 chars    |   43.629 | 356.562 (8.17x) | 326.311 (7.48x) | 322.377 (7.39x) | 308.155 (7.06x)
EOI at 1 char      | 2645.783 | 444.769 (0.17x) | 400.275 (0.15x) | 404.826 (0.15x) | 403.730 (0.15x)
Missing dash at 23 |   73.878 | 514.303 (6.96x) | 474.694 (6.43x) | 507.949 (6.88x) | 474.077 (6.42x)
Missing dash at 8  |  223.921 | 516.641 (2.31x) | 472.737 (2.11x) | 506.242 (2.26x) | 473.718 (2.12x)
Illegal char at 35 |   47.373 | 368.002 (7.77x) | 333.233 (7.03x) | 318.242 (6.72x) | 301.659 (6.37x)
Illegal char at 0  | 1729.087 | 421.511 (0.24x) | 385.217 (0.22x) | 374.047 (0.22x) | 351.944 (0.20x)

The above table is collected with BOOST_UUID_FROM_CHARS_X86_USE_VPERMI2B
defined.

In general, only the very early errors tend to perform worse in the SIMD
version and the majority of cases are still faster.

Besides BOOST_UUID_FROM_CHARS_X86_USE_VPERMI2B, the implementation also has
BOOST_UUID_TO_FROM_CHARS_X86_USE_ZMM control macro, which, if defined, enables
usage of 512-bit registers for convertting from 32-bit character types to 8-bit
integers. This code path is also slower than the 256-bit path on Golden Cove,
and therefore is disabled. The macro is provided primarily to allow for tuning
and experimentation with newer CPU microarchitectures, where the 512-bit path
may become beneficial. All of the above performance numbers were produced
without it.
2026-01-05 14:13:10 +03:00
Andrey Semashev d0c74979a9 Separated Skylake-X level of AVX-512 to a new config macro.
The new BOOST_UUID_USE_AVX512_V1 config macro indicates presence of
AVX-512F, VL, CD, BW and DQ extensions, which are supported by Intel
Skylake-X and similar processors. BOOST_UUID_USE_AVX10_1 is still
retained and indicates support for full AVX10.1 set. For now, it only
adds support for VBMI, but this list may grow in the future as new
extensions are being utilized.
2026-01-05 14:13:10 +03:00
Andrey Semashev f7718fd7cc Removed load_unaligned_si128 helper function.
This helper was used to simplify support for older CPUs, to select
between _mm_loadu_si128 and _mm_lddqu_si128 intrinsics. That code
has long been removed, and we now always use _mm_loadu_si128 to load
data. Use the intrinsic directly everywhere.
2026-01-05 14:13:10 +03:00
Andrey Semashev 1f7875c97e Added a simd_vector utility to complify SIMD constants definition.
The simd_vector template is a wrapper around an array of elements that
can automatically read that arrays as a SIMD vector. This reduces the amount
of reinterpret_casts in SIMD code that uses constants.
2026-01-05 14:13:10 +03:00
Andrey Semashev d3b72c2b71 Extracted from_chars_result to a separate header. 2026-01-05 14:13:10 +03:00
Andrey Semashev 79ecd9f563 Suppress 'conditional expression is constant' warning on MSVC. 2026-01-05 14:13:10 +03:00
Peter Dimov d5cf5c4656 Simplify operator>> 2026-01-04 04:06:55 +02:00
Andrey Semashev 211d84bdb1 Use stream character type when calling to_chars in operator<<.
This avoids potential character code conversion in ostream and instead
produces native character type directly in to_chars, which is likely
much faster.
2026-01-03 03:50:38 +03:00
Andrey Semashev 45910f2ace Use from_chars in operator>>.
This removes code duplication with from_chars and allows for reusing
a faster implementation of from_chars in operator>>.

Also, align the input character buffer for more efficient memory
accesses.
2026-01-03 03:49:48 +03:00
Peter Dimov 326e5db863 Merge pull request #185 from Lastique/feature/from_chars_result_op_bool
Add `from_chars_result::operator bool()`
2025-12-29 13:08:27 +02:00
Andrey Semashev 84afcf6372 Align buffers for to_chars for better performance of SIMD implementation. 2025-12-27 23:53:21 +03:00
Andrey Semashev 839c431152 Added x86 SIMD implementation of to_chars.
Moved the generic to_chars implementation to a separate header and made
to_chars.hpp select the implementation based on the enabled SIMD ISA
extensions. Added an x86 implementation leveraging SSSE3 and later
vector extensions. Added detection of the said extensions to config.hpp.

The performance effect on Intel Golden Cove (Core i7-12700K), gcc 13.3,
in millions of to_chars() calls per second with a 16-byte aligned output buffer:

Char     | Generic | SSE4.1           | AVX2             | AVX-512
=========+=========+==================+==================+=================
char     | 203.190 | 1059.322 (5.21x) | 1053.352 (5.18x) | 1058.089 (5.21x)
char16_t | 184.003 |  848.356 (4.61x) | 1009.489 (5.49x) | 1011.122 (5.50x)
char32_t | 202.425 |  484.801 (2.39x) |  676.338 (3.34x) |  462.770 (2.29x)

The core of the SIMD implementation is using 128-bit vectors, larger vectors
are only used to convert to the target character types. This means that for
1-byte character types all vector implementations are basically the same
(barring the extra ISA flexibility added by AVX) and for 2-byte character
types AVX2 and AVX-512 are basically the same.

For 4-byte character types, AVX-512 showed worse performance than SSE4.1 and
AVX2 on the test system. It isn't clear why that is, but it is possible that
the CPU throttles 512-bit instructions so much that the performance drops
below a 256-bit equivalent. Perhaps, there are just not enough 512-bit
instructions for the CPU to power up the full 512-bit pipeline. Therefore,
the AVX-512 code path for 4-byte character types is currently disabled and
the AVX2 path is used instead (which makes AVX2 and AVX-512 versions basically
equivalent). The AVX-512 path can be enabled again if new CPU microarchitectures
appear that will benefit from it.

Higher alignment values of the output buffer were also tested, but they did not
meaningfully improve performance.
2025-12-27 23:52:15 +03:00
Peter Dimov f797b2617f Improve from_chars, taking advantage of the fact that 0-9, A-F and a-f are consecutive in both ASCII and EBCDIC 2025-12-26 22:18:59 +02:00
Andrey Semashev 31bc20e30e Added from_chars_result::operator bool(). 2025-12-26 21:58:49 +03:00
Peter Dimov c8f97785a4 Prefer SIMD/runtime performance over constexpr-ness when __builtin_is_constant_evaluated is not available 2025-12-26 19:27:20 +02:00
Peter Dimov c963533f73 Make to_chars constexpr 2025-12-25 19:20:58 +02:00
Peter Dimov 963bb373d0 Attempt to fix GCC 5 2025-12-25 13:34:49 +02:00