mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
COMP: resolve label 64 compilation ambiguity for Mingw (fixes #3390)
COMP: restrict HashTable maxTableSize to int32 range - avoids compiler warning about possible overflow (left-shift operation) for label 64 compilations and we don't need anything larger than int32 HashTable capacity anyhow. ENH: make nearest power-of-two non-branching (previously brute-force)
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,11 +37,30 @@ License
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
void checkCanonicalSize(label size)
|
||||
{
|
||||
const auto n = HashTableCore::canonicalSize(size);
|
||||
|
||||
std::ostringstream buf;
|
||||
buf.setf(std::ios_base::hex, std::ios_base::basefield);
|
||||
buf << n;
|
||||
|
||||
Info<< "hash-table size of " << size
|
||||
<< " = " << n << " (0x" << buf.str().c_str() << ')' << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main()
|
||||
{
|
||||
for (label size : { -1, 0, 1, 7, 500, 1024, 1025, 10000, (labelMax-1)} )
|
||||
{
|
||||
checkCanonicalSize(size);
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
HashTable<scalar> table1
|
||||
{
|
||||
{"aaa", 1.0},
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -27,7 +27,6 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "HashTableCore.H"
|
||||
#include "uLabel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -36,51 +35,66 @@ namespace Foam
|
||||
defineTypeNameAndDebug(HashTableCore, 0);
|
||||
}
|
||||
|
||||
// Approximately labelMax/4
|
||||
const Foam::label Foam::HashTableCore::maxTableSize(1L << (sizeof(label)*8-3));
|
||||
|
||||
// file-scope:
|
||||
// Minimum internal table size (must be a power of two!)
|
||||
constexpr int32_t minTableSize = 8;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::HashTableCore::canonicalSize(const label requested_size)
|
||||
Foam::label Foam::HashTableCore::canonicalSize(const label size) noexcept
|
||||
{
|
||||
if (requested_size < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (requested_size >= maxTableSize)
|
||||
{
|
||||
return maxTableSize;
|
||||
}
|
||||
|
||||
// Enforce power of two for fast modulus in hash index calculations.
|
||||
// Use unsigned for these calculations.
|
||||
//
|
||||
// - The lower limit (8) is somewhat arbitrary, but if the hash table
|
||||
// is too small, there will be many direct table collisions.
|
||||
// - The upper limit (approx. labelMax/4) must be a power of two,
|
||||
// - The upper limit (approx. INT32_MAX/4) must be a power of two,
|
||||
// need not be extremely large for hashing.
|
||||
|
||||
uLabel powerOfTwo = 8u; // lower-limit
|
||||
|
||||
const uLabel size = requested_size;
|
||||
if (size <= powerOfTwo)
|
||||
if (size <= minTableSize)
|
||||
{
|
||||
return powerOfTwo;
|
||||
return (size < 1 ? 0 : minTableSize);
|
||||
}
|
||||
else if (size > maxTableSize/2)
|
||||
{
|
||||
return maxTableSize;
|
||||
}
|
||||
|
||||
if (size & (size-1)) // <- Modulus of i^2
|
||||
{
|
||||
// Determine power-of-two. Brute-force is fast enough.
|
||||
while (powerOfTwo < size)
|
||||
{
|
||||
powerOfTwo <<= 1;
|
||||
}
|
||||
// Determine power-of-two with glibc (may or may not be faster):
|
||||
//
|
||||
// return (1 << (32-__builtin_clz(int32_t(size-1))));
|
||||
|
||||
return powerOfTwo;
|
||||
if (!(size & (size-1)))
|
||||
{
|
||||
// Already a power-of-two...
|
||||
return size;
|
||||
}
|
||||
|
||||
return size;
|
||||
// Non-branching for 32-bit
|
||||
// [https://graphics.stanford.edu/~seander/bithacks.html]
|
||||
{
|
||||
uint32_t n(size);
|
||||
--n;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
// OLD:
|
||||
// Brute-force method
|
||||
//
|
||||
// uint32_t n(minTableSize);
|
||||
// while (n < uint32_t(size))
|
||||
// {
|
||||
// n <<= 1;
|
||||
// }
|
||||
// return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ SourceFiles
|
||||
#define Foam_HashTableCore_H
|
||||
|
||||
#include "label.H"
|
||||
#include "uLabel.H"
|
||||
#include "className.H"
|
||||
#include "nullObject.H"
|
||||
|
||||
@ -55,11 +54,13 @@ namespace Foam
|
||||
//- Bits that are independent of HashTable template parameters.
|
||||
struct HashTableCore
|
||||
{
|
||||
//- Maximum allowable internal table size. Approximately labelMax/4
|
||||
static const label maxTableSize;
|
||||
//- Maximum allowable internal table size (must be a power of two!).
|
||||
// - approximately (INT32_MAX/4) => 0x20000000
|
||||
// - don't need an int64 version
|
||||
static constexpr int32_t maxTableSize = (1 << (32-3));
|
||||
|
||||
//- Return a canonical (power-of-two) of the requested size.
|
||||
static label canonicalSize(const label requested_size);
|
||||
static label canonicalSize(const label size) noexcept;
|
||||
|
||||
//- Declare type-name (with debug switch)
|
||||
ClassName("HashTable");
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -64,7 +64,7 @@ MAXMINPOW(float, float, int)
|
||||
MAXMINPOW(float, int, float)
|
||||
MAXMINPOW(float, float, long)
|
||||
MAXMINPOW(float, long, float)
|
||||
#if defined(__APPLE__) && WM_LABEL_SIZE == 64
|
||||
#if (WM_LABEL_SIZE == 64) && (defined(__APPLE__) || defined(_WIN32))
|
||||
MAXMINPOW(double, double, int64_t)
|
||||
MAXMINPOW(double, int64_t, double)
|
||||
MAXMINPOW(float, float, int64_t)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -433,7 +433,7 @@ inline complex pow(const complex& x, const complex& y)
|
||||
|
||||
powFuncs(int)
|
||||
powFuncs(long)
|
||||
#if defined(__APPLE__) && WM_LABEL_SIZE == 64
|
||||
#if (WM_LABEL_SIZE == 64) && (defined(__APPLE__) || defined(_WIN32))
|
||||
powFuncs(int64_t)
|
||||
#endif
|
||||
powFuncs(float)
|
||||
|
||||
Reference in New Issue
Block a user