mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
178 lines
14 KiB
HTML
178 lines
14 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
|
|
<meta name="generator" content="Doxygen 1.9.8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<title>simdjson: CPU Architecture-Specific Implementations</title>
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="resize.js"></script>
|
|
<script type="text/javascript" src="navtreedata.js"></script>
|
|
<script type="text/javascript" src="navtree.js"></script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/searchdata.js"></script>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
|
|
<link href="doxygen-awesome-sidebar-only.css" rel="stylesheet" type="text/css"/>
|
|
<link href="doxygen-awesome-sidebar-only-darkmode-toggle.css" rel="stylesheet" type="text/css"/>
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr id="projectrow">
|
|
<td id="projectlogo"><img alt="Logo" src="logotiny.png"/></td>
|
|
<td id="projectalign">
|
|
<div id="projectname">simdjson<span id="projectnumber"> 4.6.4</span>
|
|
</div>
|
|
<div id="projectbrief">Ridiculously Fast JSON</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- end header part -->
|
|
<!-- Generated by Doxygen 1.9.8 -->
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
var searchBox = new SearchBox("searchBox", "search/",'.html');
|
|
/* @license-end */
|
|
</script>
|
|
<script type="text/javascript" src="menudata.js"></script>
|
|
<script type="text/javascript" src="menu.js"></script>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
$(function() {
|
|
initMenu('',true,false,'search.php','Search');
|
|
$(document).ready(function() { init_search(); });
|
|
});
|
|
/* @license-end */
|
|
</script>
|
|
<div id="main-nav"></div>
|
|
</div><!-- top -->
|
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
|
<div id="nav-tree">
|
|
<div id="nav-tree-contents">
|
|
<div id="nav-sync" class="sync"></div>
|
|
</div>
|
|
</div>
|
|
<div id="splitbar" style="-moz-user-select:none;"
|
|
class="ui-resizable-handle">
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
|
|
$(document).ready(function(){initNavTree('md_doc_2implementation-selection.html',''); initResizable(); });
|
|
/* @license-end */
|
|
</script>
|
|
<div id="doc-content">
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
</div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<div id="MSearchResults">
|
|
<div class="SRPage">
|
|
<div id="SRIndex">
|
|
<div id="SRResults"></div>
|
|
<div class="SRStatus" id="Loading">Loading...</div>
|
|
<div class="SRStatus" id="Searching">Searching...</div>
|
|
<div class="SRStatus" id="NoMatches">No Matches</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div><div class="header">
|
|
<div class="headertitle"><div class="title">CPU Architecture-Specific Implementations</div></div>
|
|
</div><!--header-->
|
|
<div class="contents">
|
|
<div class="textblock"><ul>
|
|
<li>Overview</li>
|
|
<li>Runtime CPU Detection</li>
|
|
<li>Inspecting the Detected Implementation</li>
|
|
<li>Querying Available Implementations</li>
|
|
<li>Manually Selecting the Implementation</li>
|
|
<li>Checking that an Implementation can Run on your System</li>
|
|
</ul>
|
|
<h1><a class="anchor" id="autotoc_md105"></a>
|
|
Overview</h1>
|
|
<p>The simdjson library takes advantage of SIMD instruction sets such as NEON, SSE and AVX to achieve much of its speed. Because these instruction sets work differently, simdjson has to compile a different version of the JSON parser for different CPU architectures, often with different algorithms to take better advantage of a given CPU!</p>
|
|
<p>The current implementations are:</p><ul>
|
|
<li>icelake: AVX-512F, AVX-512_VBMI, AVX-512_VBMI2, AVX-512_DQ, AVX-512512_CD, AVX-512_BW, AVX-512_VL (2019 Intel Ice Lake, Intel Rocket Lake, Intel Sapphire Rapids, AMD Zen 4)</li>
|
|
<li>haswell: AVX2 (2013 Intel Haswell or later, all AMD Zen processors)</li>
|
|
<li>westmere: SSE4.2 (2010 Westmere or later).</li>
|
|
<li>arm64: 64-bit ARMv8-A NEON</li>
|
|
<li>ppc64: 64-bit POWER8 and POWER9 with VSX and ALTIVEC extensions. Both big endian and little endian are implemented, depending on the compiler you are using. The library is tested on recent, little-endian, POWER systems.</li>
|
|
<li>lasx: Loongson Advanced SIMD EXtension (LASX), a 256-bit vector expansion for the LoongArch architecture.</li>
|
|
<li>lsx: Loongson SIMD EXtension (LSX), a 128-bit vector expansion for the LoongArch architecture.</li>
|
|
<li>fallback: A generic implementation that runs on any 64-bit processor.</li>
|
|
</ul>
|
|
<p>In many cases, you don't know where your compiled binary is going to run, so simdjson automatically compiles <em>all</em> the implementations into the executable. On Intel, it will include 4 implementations (icelake, haswell, westmere and fallback), on 64-bit ARM it will include just one since running dispatching is unnecessary, and on PPC it will include 2 (ppc64 and fallback).</p>
|
|
<p>On Loongson processors, LASX runtime dispatching is only enabled on GCC 15+, not on LLVM or older versions of GCC. Thus unless you compile specifically for LASX or use GCC 15+, you will not benefit from LASX support.</p>
|
|
<p>If you know more about where you're going to run and want to save the space, you can disable any of these implementations at compile time with <code>-DSIMDJSON_IMPLEMENTATION_X=0</code> (where X is ICELAKE, HASWELL, WESTMERE, ARM64, PPC64, LSX, LASX and FALLBACK).</p>
|
|
<p>The simdjson library automatically sets header flags for each implementation as it compiles; there is no need to set architecture-specific flags yourself (e.g., <code>-mavx2</code>, <code>/AVX2</code> or <code>-march=haswell</code>), and it may even break runtime dispatch and your binaries will fail to run on older processors. <em>Note:</em> for POWER9 processors make sure you compile it with <code>-mcpu=power9</code> and <code>-mtune=power9</code> to get maximum performance.</p>
|
|
<h1><a class="anchor" id="autotoc_md106"></a>
|
|
Runtime CPU Detection</h1>
|
|
<p>When you first use simdjson, it will detect the CPU you're running on, and swap over to the fastest implementation for it. This is a small, one-time cost and for many people will be paid the first time they call <code>parse()</code> or <code>load()</code>.</p>
|
|
<h1><a class="anchor" id="autotoc_md107"></a>
|
|
Inspecting the Detected Implementation</h1>
|
|
<p>You can check what implementation is running with <code>active_implementation</code>:</p>
|
|
<div class="fragment"><div class="line">cout << <span class="stringliteral">"simdjson v"</span> << SIMDJSON_VERSION << endl;</div>
|
|
<div class="line">cout << <span class="stringliteral">"Detected the best implementation for your machine: "</span> << <a class="code hl_function" href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c">simdjson::get_active_implementation</a>()->name();</div>
|
|
<div class="line">cout << <span class="stringliteral">"("</span> << <a class="code hl_function" href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c">simdjson::get_active_implementation</a>()->description() << <span class="stringliteral">")"</span> << endl;</div>
|
|
<div class="ttc" id="anamespacesimdjson_html_a05cc0046bde46e606edca27b0f9b3e0c"><div class="ttname"><a href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c">simdjson::get_active_implementation</a></div><div class="ttdeci">SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr< const implementation > & get_active_implementation()</div><div class="ttdoc">The active implementation.</div></div>
|
|
</div><!-- fragment --><p>Implementation detection will happen in this case when you first call <code>name()</code>.</p>
|
|
<h1><a class="anchor" id="autotoc_md108"></a>
|
|
Querying Available Implementations</h1>
|
|
<p>You can list all available implementations, regardless of which one was selected:</p>
|
|
<div class="fragment"><div class="line"><span class="keywordflow">for</span> (<span class="keyword">auto</span> implementation : <a class="code hl_namespace" href="namespacesimdjson.html">simdjson</a>::get_available_implementations()) {</div>
|
|
<div class="line"> cout << implementation->name() << <span class="stringliteral">": "</span> << implementation->description() << endl;</div>
|
|
<div class="line">}</div>
|
|
<div class="ttc" id="anamespacesimdjson_html"><div class="ttname"><a href="namespacesimdjson.html">simdjson</a></div><div class="ttdoc">The top level simdjson namespace, containing everything the library provides.</div><div class="ttdef"><b>Definition</b> <a href="arm64_2base_8h_source.html#l00008">base.h:8</a></div></div>
|
|
</div><!-- fragment --><p>And look them up by name:</p>
|
|
<div class="fragment"><div class="line">cout << <a class="code hl_function" href="namespacesimdjson.html#abdd2db13c7545fea225086c6037657b5">simdjson::get_available_implementations</a>()[<span class="stringliteral">"fallback"</span>]->description() << endl;</div>
|
|
<div class="ttc" id="anamespacesimdjson_html_abdd2db13c7545fea225086c6037657b5"><div class="ttname"><a href="namespacesimdjson.html#abdd2db13c7545fea225086c6037657b5">simdjson::get_available_implementations</a></div><div class="ttdeci">SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list & get_available_implementations()</div><div class="ttdoc">The list of available implementations compiled into simdjson.</div></div>
|
|
</div><!-- fragment --><p> When an implementation is not available, the bracket call <code><a class="el" href="namespacesimdjson.html#abdd2db13c7545fea225086c6037657b5" title="The list of available implementations compiled into simdjson.">simdjson::get_available_implementations()</a>[name]</code> will return the null pointer.</p>
|
|
<p>The available implementations have been compiled but may not necessarily be run safely on your system see Checking that an Implementation can Run on your System.</p>
|
|
<h1><a class="anchor" id="autotoc_md109"></a>
|
|
Manually Selecting the Implementation</h1>
|
|
<p>If you're trying to do performance tests or see how different implementations of simdjson run, you can select the CPU architecture yourself:</p>
|
|
<div class="fragment"><div class="line"><span class="comment">// Use the fallback implementation, even though my machine is fast enough for anything</span></div>
|
|
<div class="line"><a class="code hl_function" href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c">simdjson::get_active_implementation</a>() = <a class="code hl_function" href="namespacesimdjson.html#abdd2db13c7545fea225086c6037657b5">simdjson::get_available_implementations</a>()[<span class="stringliteral">"fallback"</span>];</div>
|
|
</div><!-- fragment --><p>You are responsible for ensuring that the requirements of the selected implementation match your current system. Furthermore, you should check that the implementation is available before setting it to <code><a class="el" href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c" title="The active implementation.">simdjson::get_active_implementation()</a></code> by comparing it with the null pointer.</p>
|
|
<div class="fragment"><div class="line"><span class="keyword">auto</span> my_implementation = <a class="code hl_function" href="namespacesimdjson.html#abdd2db13c7545fea225086c6037657b5">simdjson::get_available_implementations</a>()[<span class="stringliteral">"haswell"</span>];</div>
|
|
<div class="line"><span class="keywordflow">if</span> (! my_implementation) { exit(1); }</div>
|
|
<div class="line"><span class="keywordflow">if</span> (! my_implementation->supported_by_runtime_system()) { exit(1); }</div>
|
|
<div class="line"><a class="code hl_function" href="namespacesimdjson.html#a05cc0046bde46e606edca27b0f9b3e0c">simdjson::get_active_implementation</a>() = my_implementation;</div>
|
|
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md110"></a>
|
|
Checking that an Implementation can Run on your System</h1>
|
|
<p>You should call <code>supported_by_runtime_system()</code> to compare the processor's features with the need of the implementation.</p>
|
|
<div class="fragment"><div class="line"><span class="keywordflow">for</span> (<span class="keyword">auto</span> implementation : <a class="code hl_namespace" href="namespacesimdjson.html">simdjson</a>::get_available_implementations()) {</div>
|
|
<div class="line"> <span class="keywordflow">if</span> (implementation->supported_by_runtime_system()) {</div>
|
|
<div class="line"> cout << implementation->name() << <span class="stringliteral">": "</span> << implementation->description() << endl;</div>
|
|
<div class="line"> }</div>
|
|
<div class="line">}</div>
|
|
</div><!-- fragment --><p>The call to <code>supported_by_runtime_system()</code> may be relatively expensive. Do not call <code>supported_by_runtime_system()</code> each time you parse a JSON input (for example). It is meant to be called a handful of times at most in the life of a program. </p>
|
|
</div></div><!-- contents -->
|
|
</div><!-- PageDoc -->
|
|
</div><!-- doc-content -->
|
|
<!-- start footer part -->
|
|
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
|
<ul>
|
|
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8 </li>
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|