Skip to content

Commit

Permalink
add prvhash82 variants
Browse files Browse the repository at this point in the history
needs HAVE_INT128. should be 2x faster, but is not
  • Loading branch information
rurban committed Aug 14, 2020
1 parent 4d9d398 commit 2b08451
Show file tree
Hide file tree
Showing 8 changed files with 3,287 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG")
include (CheckTypeSize)
check_type_size (__int64 __INT64)
check_type_size (int64_t INT64_T)
check_type_size (__uint128_t __UINT128_T)

# TODO: rather parse `$CC -march=native -dM -E - <<< ''` [gh #10]
if (NOT (CMAKE_CROSSCOMPILING))
Expand Down Expand Up @@ -257,6 +258,10 @@ ELSE (AVX512_TRUE)
message(WARNING "AVX512 not available")
ENDIF (AVX512_TRUE)

IF(HAVE___UINT128_T)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_INT128")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_INT128")
ENDIF()
IF(HAVE_INT64_T)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_INT64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_INT64")
Expand Down
16 changes: 16 additions & 0 deletions Hashes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,22 @@ inline void prvhash42_128test ( const void * key, int len, unsigned seed, void *
memcpy (out, hash, 16);
}

#ifdef HAVE_INT128
#include "prvhash82.h"
inline void prvhash82_64test ( const void * key, int len, unsigned seed, void * out )
{
uint8_t hash[8] = {0};
prvhash82 ((const uint8_t *)key, len, hash, 8, (uint64_t)seed, 0, 0);
memcpy (out, hash, 8);
}
inline void prvhash82_128test ( const void * key, int len, unsigned seed, void * out )
{
uint8_t hash[16] = {0};
prvhash82 ((const uint8_t *)key, len, hash, 16, (uint64_t)seed, 0, 0);
memcpy (out, hash, 16);
}
#endif

// objsize: 408dd0 - 4090ae: 734
#include "mx3/mx3.h"
inline void mx3hash64_test ( const void * key, int len, uint32_t seed, void * out ) {
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ SMhasher
| [prvhash42_32](doc/prvhash42_32.txt) | 455.52 | 114.86 | 200.45 (4) | 157 | |
| [prvhash42_64](doc/prvhash42_64.txt) | 420.43 | 157.90 | 236.45 (2) | 157 | |
| [prvhash42_128](doc/prvhash42_128.txt) | 408.58 | 167.06 | 265.71 (6) | 157 | |
| [prvhash82_64](doc/prvhash82_64.txt) | 480.58 | 119.48 | 219.63 (2) | 157 | needs __uint128_t |
| [prvhash82_128](doc/prvhash82_128.txt) | 419.85 | 151.18 | 237.18 (6) | 157 | TwoBytes, needs __uint128_t|
| [chaskey](doc/chaskey.txt) | 735.85 | 168.05 | 336.07 (4) |1609 | |
| [SipHash](doc/SipHash.txt) | 958.78 | 141.84 | 278.15 (3) |1071 | |
| [HalfSipHash](doc/HalfSipHash.txt) | 741.59 | 122.25 | 256.22 (20)| 700 | zeroes |
Expand Down
1,631 changes: 1,631 additions & 0 deletions doc/prvhash82_128.txt

Large diffs are not rendered by default.

1,480 changes: 1,480 additions & 0 deletions doc/prvhash82_64.txt

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions doc/table.html
Original file line number Diff line number Diff line change
Expand Up @@ -835,13 +835,15 @@ <h1 id="smhasher">SMhasher</h1>
<td align="right">200.45 (4) </td>
<td align="right">157</td>
<td align="left"></td>
</tr>
<tr class="good">
<td align="left"><a href="prvhash42_64.txt">prvhash42_64</a></td>
<td align="right">420.43</td>
<td align="right">157.90</td>
<td align="right">236.45 (2) </td>
<td align="right">157</td>
<td align="left"></td>
</tr>
<tr class="good">
<td align="left"><a href="prvhash42_128.txt">prvhash42_128</a></td>
<td align="right">408.58</td>
Expand All @@ -851,6 +853,22 @@ <h1 id="smhasher">SMhasher</h1>
<td align="left"></td>
</tr>
<tr class="good">
<td align="left"><a href="prvhash82_64.txt">prvhash82_64</a></td>
<td align="right">480.58</td>
<td align="right">119.48</td>
<td align="right">219.63 (2) </td>
<td align="right">157</td>
<td align="left">needs __uint128_t</td>
</tr>
<tr class="poor">
<td align="left"><a href="prvhash82_128.txt">prvhash82_128</a></td>
<td align="right">419.85</td>
<td align="right">151.18</td>
<td align="right">237.18 (6) </td>
<td align="right">157</td>
<td align="left">TwoBytes, needs __uint128_t</td>
</tr>
<tr class="good">
<td align="left"><a href="chaskey.txt">chaskey</a></td>
<td align="right">735.85</td>
<td align="right">168.05</td>
Expand Down
4 changes: 4 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ HashInfo g_hashes[] =
{ prvhash42_32test, 32, 0x6588C6C3, "prvhash42_32", "prvhash42opt 32bit", GOOD },
{ prvhash42_64test, 64, 0xFDFEDA1E, "prvhash42_64", "prvhash42 64bit", GOOD },
{ prvhash42_128test, 128, 0xFB4CE766, "prvhash42_128","prvhash42 128bit", GOOD },
#endif
#ifdef HAVE_INT128
{ prvhash82_64test, 64, 0x07BBB680, "prvhash82_64", "prvhash82 64bit", GOOD },
{ prvhash82_128test, 128, 0x2347E988, "prvhash82_128","prvhash82 128bit", POOR },
#endif
{ siphash_test, 64, 0xC58D7F9C, "SipHash", "SipHash 2-4 - SSSE3 optimized", GOOD },
{ halfsiphash_test, 32, 0xA7A05F72, "HalfSipHash", "HalfSipHash 2-4, 32bit", GOOD },
Expand Down
131 changes: 131 additions & 0 deletions prvhash82.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @file prvhash82.h
*
* @brief The inclusion file for the "prvhash82" hash function. Hash length
* increment = 8.
*
* @mainpage
*
* @section intro_sec Introduction
*
* Description is available at https://github.com/avaneev/prvhash
*
* @section license License
*
* Copyright (c) 2020 Aleksey Vaneev
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* @version 2.5
*/

//$ nocpp

#ifndef PRVHASH82_INCLUDED
#define PRVHASH82_INCLUDED

#include <stdint.h>
#include <string.h>

/**
* PRVHASH hash function (128-bit variables with 64-bit hash word). Produces
* hash of the specified Message.
*
* @param Message Message to produce hash from.
* @param MessageLen Message length, in bytes.
* @param[out] Hash The resulting hash. If both InitLCG and InitSeed are
* non-zero, the hash will not be initially reset to 0, otherwise the hash
* should be pre-initialized with random bytes.
* @param HashLen The required hash length, in bytes, should be >= 8, in
* increments of 8.
* @param SeedXOR Optional value, to XOR the default seed with. To use the
* default seed, set to 0. If both InitLCG and InitSeed are non-zero, this
* SeedXOR is ignored and should be set to 0. Otherwise, the SeedXOR value
* can have any bit length, and is used only as an additional entropy source.
* @param InitLCG If both InitLCG and InitSeed are non-zero, both values
* will be used as initial state of the hash function. Full 128-bit random
* value should be supplied in this case. See the considerations below.
* @param InitSeed If both InitLCG and InitSeed are non-zero, both values
* will be used as initial state of the hash function. Full 128-bit random
* value should be supplied in this case.
*/

inline void prvhash82( const uint8_t* const Message, const int MessageLen,
uint8_t* const Hash, const int HashLen, const __uint128_t SeedXOR,
const __uint128_t InitLCG, const __uint128_t InitSeed )
{
__uint128_t lcg; // Multiplier inspired by LCG. This is not a prime
// number. It is a random sequence of bits. This value can be
// regenerated at will, possibly using various statistical search
// methods. The best strategies: 1) Compose this number from 16-bit
// random values that have 6 to 10 random bits set; 2) Use a 128-bit
// random value that has 60-68 random bits set. An important
// consideration here is to pass the 16-bit Sparse test by default.
__uint128_t Seed; // Generated similarly to "lcg".

if( InitLCG == 0 && InitSeed == 0 )
{
lcg = 15267459991392010589ULL;
lcg <<= 64;
lcg |= 14473286605592752231ULL;
Seed = 7928988912013905173ULL;
Seed <<= 64;
Seed |= 1846177453121048234ULL;
Seed ^= SeedXOR;

memset( Hash, 0, HashLen );
}
else
{
lcg = InitLCG;
Seed = InitSeed;
}

const int hl8 = ( HashLen >> 3 );
const uint64_t lmsg = ( MessageLen == 0 ? 0 : ~Message[ MessageLen - 1 ]);
const int ml2 = MessageLen + ( MessageLen & 1 ) +
( MessageLen < 4 && MessageLen > 0 ? 2 : 0 );

int c = ml2 + hl8 + hl8 - ml2 % hl8;
int hpos = 0;
int k;

for( k = 0; k < c; k += 2 )
{
const uint64_t msg = ( (uint64_t) ( k < MessageLen - 1 ?
Message[ k + 1 ] : lmsg ) << 8 ) |
( k < MessageLen ? (uint64_t) Message[ k ] : lmsg );

Seed *= lcg;
uint64_t* const hc = (uint64_t*) &Hash[ hpos ];
const uint64_t ph = *hc;
*hc ^= (uint64_t) ( Seed >> 64 );
Seed ^= ph ^ msg;
lcg += Seed;

hpos += 8;

if( hpos == HashLen )
{
hpos = 0;
}
}
}

#endif // PRVHASH82_INCLUDED

0 comments on commit 2b08451

Please sign in to comment.