-r--r--r-- 16412 djbsort-20260127/doc/html/download.html raw
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
html{overflow-y:scroll;background-color:#012345}
body{font-family:"Noto Sans","Droid Sans","DejaVu Sans","Arial",sans-serif;line-height:1.5}
tt,code{background-color:#f0f0f0;font-family:"Noto Sans Mono","Droid Sans Mono","DejaVu Sans Mono","Courier New",monospace,sans-serif;font-size:1em;}
pre{margin-left:3em}
p,ul,ol,blockquote,pre{font-size:1.0em;line-height:1.6}
li p{font-size:1.0em}
blockquote p{font-size:1.0em}
h1{font-size:1.5em}
h2{font-size:1.3em}
h3{font-size:1.0em}
h1 a{text-decoration:none}
table{border-collapse:collapse}
th,td{border:1px solid black}
table a{text-decoration:none}
table tr{font-size:1.0em;line-height:1.6em}
table tr{font-size:1.0em;line-height:1.5}
tbody tr:nth-child(2n+1){background-color:#f0ffff}
tbody tr:nth-child(2n+2){background-color:#fffff0}
#headline{display:block;margin:0;padding:0;color:#ffffff;background-color:#012345}
#headline .text{font-weight:bold;font-size:1.0em}
#headline input{display:none}
#nav ul{margin:0;padding:0}
#nav li{list-style-type:none;margin:0;padding:0}
.navtop{padding-bottom:0.5em;font-weight:bold;font-size:1.0em}
.navtop{background-color:#012345;color:#ffffff}
#nav .here{background-color:#012345;color:#ffffff}
#nav .away{background-color:#012345;color:#ffffff}
#nav .away a{text-decoration:none;display:block;color:#ffffff}
#nav .away a:hover,.away a:active{text-decoration:underline}
#hidemenu{visibility:hidden;display:none;overflow:hidden;position:fixed;top:0;left:0;height:100%;width:100%}
.main{padding:5px}
.main{background-color:#ffffff}
.pagetitle{font-size:1.4em;font-weight:bold}
@media only screen and (min-width:512px) {
.navtop{padding-top:5px}
#headline{top:0;margin:0;width:160px;height:100%;position:fixed;overflow:auto}
#headline .noselect{display:none}
#headline #nav{visibility:visible;display:block;width:auto;height:auto}
.main{margin-left:170px}
#headline #hidemenu{visibility:hidden}
}
@media not screen and (min-width:512px) {
#headline .noselect{-webkit-user-select:none;-ms-user-select:none;user-select:none;}
#headline #nav #navbot{visibility:hidden;position:fixed;top:0;left:-70%;z-index:2;transition:0.2s;margin:0;padding:0}
#headline input:checked ~ #nav #navbot{height:100%;position:fixed;top:0;left:0;visibility:visible;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;vertical-align:center;font-size:1.0em;width:70%;overflow:auto}
#headline input:checked ~ #hidemenu{visibility:visible;display:block;background:black;opacity:0.3;z-index:1}
}
</style>
<title>
djbsort: Download</title>
</head>
<body>
<label id=headline>
<input type=checkbox />
<nav id=nav>
<div class=navtop>
<span class=noselect>≡</span>
djbsort</div>
<ul id=navbot>
<li class=away><a href=index.html>Intro</a>
</li><li class=here>Download
</li><li class=away><a href=install.html>Install</a>
</li><li class=away><a href=test.html>Test</a>
</li><li class=away><a href=api.html>API</a>
</li><li class=away><a href=speed.html>Speed</a>
</li><li class=away><a href=security.html>Security</a>
</li><li class=away><a href=verif.html>Verification</a>
</li><li class=away><a href=internals.html>Internals</a>
</li><li class=away><a href=license.html>License</a>
</li><li class=away><a href=refs.html>References</a>
</li><li class=away><a href=comparison.html>Comparison</a>
</li></ul></nav>
<div id=hidemenu></div>
</label>
<div class=main>
<div class=pagetitle>djbsort: Download</div>
<p>To download and unpack the latest version of djbsort:</p>
<pre><code>wget -m https://sorting.cr.yp.to/djbsort-latest-version.txt
version=$(cat sorting.cr.yp.to/djbsort-latest-version.txt)
wget -m https://sorting.cr.yp.to/djbsort-$version.tar.gz
tar -xzf sorting.cr.yp.to/djbsort-$version.tar.gz
cd djbsort-$version
</code></pre>
<p>Then <a href="install.html">install</a>
and <a href="test.html">test</a>.</p>
<h2 id="changelog">Archives and changelog (reverse chronological)</h2>
<p><a href="djbsort-20260127.tar.gz"><code>djbsort-20260127.tar.gz</code></a> <a href="djbsort-20260127.html">browse</a></p>
<p><strong>Algorithm.</strong>
The vectorizable sorting algorithm has been redesigned from the ground up for higher speed and improved generality.
Both <code>int32/avx2</code> and the new <code>int64/avx2</code> are now automatically generated by <code>autogen/sort</code>.</p>
<p><strong>C API.</strong>
There are new <code>uint64</code> and <code>float64</code> wrappers similar to the previous <code>uint32</code> and <code>float32</code> wrappers.
There are also new reverse-sorting wrappers
<code>int32down</code>, <code>uint32down</code>, <code>float32down</code>,
<code>int64down</code>, <code>uint64down</code>, <code>float64down</code>.</p>
<p>Each wrapper now has an <code>avx2useint</code> implementation to supplement the <code>useint</code> implementation.
All of these implementations are now automatically generated by <code>autogen/useint</code>.</p>
<p>All external symbols are now within the <code>djbsort</code> namespace
(meaning C symbols beginning <code>djbsort_</code>, not C++ symbols <code>djbsort::</code>).</p>
<p><strong>Packaging.</strong>
The infrastructure is now a variant of the packaging infrastructure
from <a href="https://lib25519.cr.yp.to">lib25519</a>
and <a href="https://lib.mceliece.org">libmceliece</a>.
This provides
cross-compilation,
namespace tests,
instruction-set tests,
tests for branches in the binaries,
automatic run-time selection of implementations,
etc.</p>
<p><strong>Internals.</strong>
The software now uses
<a href="https://cr.yp.to/papers.html#cryptoint">cryptoint</a>
to provide efficient comparators (<code>minmax</code>) on many CPUs
while at the same time protecting against current compilers converting arithmetic into branches.</p>
<p><strong>Benchmarking.</strong>
Cycle counting now relies on
<a href="https://cpucycles.cr.yp.to">libcpucycles</a>,
both for sortbench and for the installed <code>djbsort-speed</code>.</p>
<p>An updated version of the sortbench package is now included in the djbsort package
and supersedes the separately released sortbench package.
The updated version compares the aspas, djbsort, far, herf, stdsort, vqsort, vxsort, and x86simdsort libraries
for <code>int32</code> and <code>int64</code> at many different array sizes;
systematically varies the data permutations, the physical tagging (running each benchmark program 8 times), and the array alignment;
and plots <a href="https://cr.yp.to/papers.html#rsrst">stabilized quartiles</a>.</p>
<p><strong>Verification.</strong>
The <code>verifymany</code> driver has been rewritten,
and now analyzes all of the <code>int32</code> and <code>int64</code> implementations compiled into the library.</p>
<p>For <code>minmax</code>:
Speedups.
Less memory usage.
Computations for concrete inputs are now integrated,
both for constant propagation and for sanity checks.
More peephole optimizations for the code being analyzed,
moving further towards allowing a simpler symbolic-execution backend.
Almost all rewrite rules are now handled systematically with a DSL.
A separate <code>checkrules</code> script uses an SMT solver to verify rewrite rules expressed in the DSL.</p>
<p>For <code>unroll</code>:
Various tweaks,
such as disabling some angr peephole optimizations
and modifying angr's CPUID to report AVX2.</p>
<hr />
<p><a href="sortbench-20240116.tar.gz"><code>sortbench-20240116.tar.gz</code></a> <a href="sortbench-20240116.html">browse</a></p>
<p>Intermediate release of sortbench as a separate package.</p>
<hr />
<p><a href="djbsort-20190516.tar.gz"><code>djbsort-20190516.tar.gz</code></a> <a href="djbsort-20190516.html">browse</a></p>
<p><strong>Benchmarking.</strong>
Speed tests now call cpucycles() before setting resource limits.
This is important on platforms where cpucycles() needs to read files.</p>
<p><strong>Verification.</strong>
Support for SignExt and several more peephole optimizations,
working towards support for simpler symbolic-execution backend.
Various updates to work with angr8 and python3.</p>
<hr />
<p><a href="djbsort-20180729.tar.gz"><code>djbsort-20180729.tar.gz</code></a> <a href="djbsort-20180729.html">browse</a></p>
<p><strong>Algorithm.</strong>
Rewrite of the core <code>int32/avx2</code> implementation
for (1) higher speed and (2) reduced memory consumption.
Stack allocation is now at most a few kilobytes,
even for gigantic arrays.</p>
<p>Internally,
the sorting algorithm
is now mostly bitonic to simplify indexing,
although odd-even speedups are still applied when convenient.
Lanes are complemented
to take the down-up decision out of the inner loops.</p>
<p>As in previous djbsort versions,
data is sorted first in vector lanes
and then transposed for final merges,
reducing the overall number of vector permutations.
Unlike previous versions,
transposition is done in-place.
The transposition in this version
is bit-reversal on the outer 6 bits
(bottom 3 bits and the top 3 bits),
but leaves intermediate bits alone.
Non-power-of-2 array sizes
are handled by an extra, more traditional, merge step.</p>
<p>Sizes 2, 3, 4, 5, 6, 7, 8, 16, 32 are now special-cased.
Non-power-of-2 sizes below 256
are padded to the next power of 2.</p>
<p>Portable implementations:
The out-of-place
<code>int32/portable1</code> and <code>int32/portable2</code> implementations
are now gone;
the in-place
<code>int32/portable3</code> and <code>int32/portable4</code> implementations
remain.</p>
<p><strong>C API.</strong>
<code>float32_sort</code> is now supported.
The arithmetic in the reduction from <code>float32</code> to <code>int32</code>
is <code>int32</code> 31-bit right shift, <code>uint32</code> 1-bit right shift, xor;
this is slightly more efficient
than the reduction from <code>float32</code> to <code>uint32</code>
from <a href="refs.html#2001-herf">2001 Herf</a>.</p>
<p><strong>Compiling.</strong>
Tests now have more variation (without much slowdown):
the <code>uint32</code> test cases
now deviate from <code>int32</code> in more than the sign;
<code>float32</code> uses floating-point numbers that aren't integers;
<code>int32</code> does more loops for small cases,
and some larger cases.</p>
<p><strong>Internals.</strong>
API for 2-input sorting is now <code>MINMAX</code> macro
operating on two inputs in place.</p>
<p>Better inline assembly from Jason Donenfeld for 2-input sorting:
more flexibility in compiler's register allocation.</p>
<p>The package version number is now automatically copied to <code>version.c</code>
as the implementation version number
for implementations that don't provide <code>version.c</code>.</p>
<p><strong>Verification.</strong>
<code>minmax</code> now supports more peephole optimizations
for complemented bitonic sorting and for padding:
<code>xor(s,xor(s,t))</code> ⇒ <code>t</code>;
<code>xor(-1,s)</code> ⇒ <code>invert(s)</code>;
<code>Reverse(Reverse(s))</code> ⇒ <code>s</code>;
<code>signedmin(invert(s),invert(t))</code> ⇒ <code>invert(signedmax(s,t))</code>;
<code>signedmax(invert(s),invert(t))</code> ⇒ <code>invert(signedmin(s,t))</code>;
<code>invert(s)[high:low]</code> ⇒ <code>invert(s[high:low])</code>;
<code>s[bits-1:0]</code> ⇒ <code>s</code>;
<code>s[high:low][high2:low2]</code> ⇒ <code>s[high2+low:low2+low]</code>;
<code>Concat(...)[high:low]</code> ⇒ <code>...[high-pos:low-pos]</code> when possible;
<code>Reverse(s)[high:low]</code> ⇒ <code>Reverse(s[...])</code> when possible;
eliminate <code>signedmin</code>/<code>signedmax</code>
when one input is the minimum or maximum constant.</p>
<p><code>verifymany</code> now includes the implementation version number
on <code>verified</code> lines.</p>
<hr />
<p><a href="djbsort-20180717.tar.gz"><code>djbsort-20180717.tar.gz</code></a> <a href="djbsort-20180717.html">browse</a></p>
<p><strong>C API.</strong>
<code>uint32_sort</code> is now supported, joining <code>int32_sort</code>.
(Internally, <code>uint32_sort</code> simply flips top bits and calls <code>int32_sort</code>.
Inlining the <code>int32_sort</code> code and integrating the flips into the initial and final passes
would be noticeably faster.
Adapting the <code>int32</code> code to handle <code>uint32</code> directly, without flips,
would be noticeably faster on platforms that have all relevant <code>uint32</code> instructions.
However, the separate flip has the virtue of minimizing the code size for the library.)</p>
<p>The <code>.h</code> files should work from C++ now. (Not tested yet.)</p>
<p><strong>Compiling and benchmarking.</strong>
<code>./do</code> now finishes
by running <code>int32-speed</code>.</p>
<p><code>int32-speed</code> now prints
cycle-count overhead;
cycle counts for some intermediate sizes;
and cycles per byte.</p>
<p>The default compiler list is now revamped,
and shorter.</p>
<p><strong>Internals.</strong>
There is now a unified internal API for 2-input sorting.
This API has the following interchangeable implementations:
<code>int32_minmax.c</code> (portable);
<code>int32_minmax_x86.c</code> (using <code>cmovg</code> in assembly);
presumably more later.
These implementations are now shared by the higher-level sorting code.</p>
<p><strong>Verification.</strong>
<code>verifymany</code> now prints a "<code>verified</code>" line for each successful verification.</p>
<p>Verification is now flexible enough
to handle the <code>portable</code> implementations,
at least compiled on amd64
with typical compiler options.</p>
<p>Internally,
Z3 is no longer asked
to simplify symbolic expressions.
All necessary simplifications
are handled by peephole optimizations
(in djbsort's <code>minmax</code>,
or in patches from djbsort to angr's claripy).
Added peephole optimizations in <code>minmax</code>:
<code>If(c,constbit1,constbit0)</code> ⇒ <code>c</code>;
<code>xor(c,constbit1)</code> ⇒ <code>invert(c)</code>;
<code>equal(c,bit0)</code> ⇒ <code>invert(c)</code>;
<code>invert(invert(c))</code> ⇒ <code>c</code>.</p>
<p>More operations supported in input DSL
for <code>minmax</code> and <code>tryinput</code>:
<code>xor</code>; <code>or</code>; <code>and</code>;
<code>add</code>; <code>sub</code>; <code>mul</code>;
<code>equal</code>;
<code>signedlt</code>;
<code>signedrshift</code>;
any number of inputs to concatenation.
Reduced redundancy in <code>minmax</code> input grammar.
Some work on cleaning up DSL syntax.</p>
<hr />
<p><a href="djbsort-20180710.tar.gz"><code>djbsort-20180710.tar.gz</code></a> <a href="djbsort-20180710.html">browse</a></p>
<p>Original release.</p>
<hr />
<h2>Archive of angr patches</h2>
<p>To simplify the <code>unroll</code> and <code>minmax</code> tools,
djbsort contributed some patches to angr back in 2018:</p>
<ul>
<li>
<p><a href="angrpatch1.txt"><code>angrpatch1.txt</code></a>:
Support the AVX2 <code>vpunpck</code> instructions.
Otherwise angr was crashing on djbsort.</p>
</li>
<li>
<p><a href="angrpatch2.txt"><code>angrpatch2.txt</code></a>:
Superseded by <code>angrpatch3.txt</code>.</p>
</li>
<li>
<p><a href="angrpatch3.txt"><code>angrpatch3.txt</code></a>:
Various peephole optimizations.
Specifically:
C idiom for signedmin;
C idiom for signedmax;
<code>reverse(concat(reverse(x),reverse(y)))</code>
⇒ <code>concat(y,x)</code> if lengths are multiples of 8;
<code>reverse(concat(reverse(x),0))</code>
⇒ <code>concat(0,x)</code> if lengths are multiples of 8;
same for any combinations of reversals and zeros;
<code>reverse(extract(reverse(x),high,low))</code>
⇒ <code>extract(x,xbits-1-low,xbits-1-high)</code>
if <code>xbits</code> and <code>high+1</code> and <code>low</code> are
multiples of 8;
<code>concat(a,b) ^ concat(c,d)</code>
⇒ <code>concat(a^c,b^d)</code> if sizes match;
<code>concat(a,b) & concat(c,d)</code>
⇒ <code>concat(a&c,b&d)</code> if sizes match;
<code>(SignExt(n,v)>>s)[vbits-1:0]</code>
⇒ <code>v>>(s[vbits-1:0])</code>
if <code>n+vbits<2**(vbits-1)</code>.</p>
</li>
<li>
<p><a href="angrpatch4.txt"><code>angrpatch4.txt</code></a>:
Portion of <code>angrpatch3.txt</code>
beyond claripy commit <code>7826167ecb4f965acb55f7b0d3a4677588242c28</code>.</p>
</li>
</ul><hr><font size=1><b>Version:</b>
This is version 2026.01.27 of the "Download" web page.
</font>
</div>
</body>
</html>