Skip to content

Commit f867efa

Browse files
committed
parse_unsigned uses SSE2
1 parent 6cb8c49 commit f867efa

File tree

1 file changed

+43
-19
lines changed

1 file changed

+43
-19
lines changed

include/boost/json/detail/sse2.hpp

+43-19
Original file line numberDiff line numberDiff line change
@@ -313,39 +313,63 @@ inline int count_digits( char const* p ) noexcept
313313

314314
// parse_unsigned
315315

316+
inline
317+
uint64_t
318+
parse_four_digits(void const* p) noexcept
319+
{
320+
#ifdef BOOST_JSON_USE_SSE2
321+
auto const c0 = _mm_cvtsi32_si128(0x0F0F0F0F);
322+
auto v0 = _mm_and_si128(_mm_loadu_si32(p), c0);
323+
324+
// auto const c1 = _mm_cvtsi64_si128(0x0001'000A'0064'03E8);
325+
auto const c1 = _mm_setr_epi16(1000, 100, 10, 1, 0, 0, 0, 0);
326+
327+
auto v1 = _mm_unpacklo_epi8( v0, _mm_setzero_si128() );
328+
auto v2 = _mm_madd_epi16(v1, c1);
329+
auto v3 = _mm_srli_epi64(v2, 32);
330+
auto v4 = _mm_add_epi32(v2, v3);
331+
return static_cast<uint32_t>( _mm_cvtsi128_si32(v4) );
332+
#else // BOOST_JSON_USE_SSE2
333+
uint32_t v;
334+
std::memcpy( &v, p, 4 );
335+
endian::native_to_little_inplace(v);
336+
v = (v & 0x0F0F0F0F) * 2561 >> 8;
337+
v = (v & 0x00FF00FF) * 6553601 >> 16;
338+
return v;
339+
#endif // BOOST_JSON_USE_SSE2
340+
}
341+
316342
inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noexcept
317343
{
318-
char const* e = p + n;
344+
auto const e = p + n;
319345

320-
if( n & 1 )
346+
if(n & 2)
321347
{
322-
r = r * 10 + p[0] - '0';
323-
++p;
348+
uint32_t v0 = 0;
349+
std::memcpy( &v0, p, 2 );
350+
endian::native_to_little_inplace(v0);
351+
v0 = v0 & 0x0F0F;
352+
r = (r * 100) + ((v0 & 0xFF) * 10) + (v0 >> 8);
353+
p += 2;
324354
}
325-
if( n & 2 )
355+
if(n & 1)
326356
{
327-
r = r * 10 + p[0] - '0';
328-
r = r * 10 + p[1] - '0';
329-
p += 2;
357+
r = (r * 10) + (p[0] & 0x0F);
358+
p += 1;
330359
}
331-
#if BOOST_JSON_ARCH == 64
360+
361+
#if defined(BOOST_JSON_USE_SSE2) || (BOOST_JSON_ARCH == 64)
362+
while(p < e)
363+
#else // !defined(BOOST_JSON_USE_SSE2) && (BOOST_JSON_ARCH == 32)
332364
if( n & 4 )
333-
#else
334-
while( p != e )
335365
#endif
336366
{
337-
uint32_t v;
338-
std::memcpy( &v, p, 4 );
339-
endian::native_to_little_inplace(v);
340-
v = (v & 0x0F0F0F0F) * 2561 >> 8;
341-
v = (v & 0x00FF00FF) * 6553601 >> 16;
342-
343-
r = r * 10000 + v;
367+
r = r * 10000 + parse_four_digits(p);
344368
p += 4;
345369
}
346370

347371
#if BOOST_JSON_ARCH == 64
348-
while( p != e )
372+
while( p < e )
349373
{
350374
uint64_t v;
351375
std::memcpy( &v, p, 8 );

0 commit comments

Comments
 (0)