mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
bugfix PackedList for non-optimized compilation
- use shift-right instead of shift-left formulation to avoid wrong behaviour with non-optimized compilation when the packed items fit exactly in the available number of bits.
This commit is contained in:
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
check for consistent behaviour with non-optimized code
|
||||||
|
*/
|
||||||
|
|
||||||
|
EXE_INC = \
|
||||||
|
-DFULLDEBUG -g -O0
|
||||||
|
|
||||||
|
|||||||
@ -34,9 +34,46 @@ Description
|
|||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "IFstream.H"
|
#include "IFstream.H"
|
||||||
#include "PackedBoolList.H"
|
#include "PackedBoolList.H"
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
|
template<unsigned nBits>
|
||||||
|
inline void reportInfo()
|
||||||
|
{
|
||||||
|
unsigned offset = PackedList<nBits>::packing();
|
||||||
|
|
||||||
|
unsigned useSHL = ((1u << (nBits * offset)) - 1);
|
||||||
|
unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset));
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "PackedList<" << nBits << ">" << nl
|
||||||
|
<< " max_value: " << PackedList<nBits>::max_value() << nl
|
||||||
|
<< " packing: " << PackedList<nBits>::packing() << nl
|
||||||
|
<< " utilization: " << (nBits * offset) << nl;
|
||||||
|
|
||||||
|
Info<< " Masking:" << nl
|
||||||
|
<< " shift << " << unsigned(nBits * offset) << nl
|
||||||
|
<< " shift >> " << unsigned((sizeof(unsigned)*CHAR_BIT) - nBits * offset)
|
||||||
|
<< nl;
|
||||||
|
|
||||||
|
hex(Info);
|
||||||
|
Info<< " maskLower: " << PackedList<nBits>::maskLower(PackedList<nBits>::packing())
|
||||||
|
<< nl
|
||||||
|
<< " useSHL: " << useSHL << nl
|
||||||
|
<< " useSHR: " << useSHR << nl;
|
||||||
|
|
||||||
|
if (useSHL != useSHR)
|
||||||
|
{
|
||||||
|
Info<< "WARNING: different results for SHL and SHR" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl;
|
||||||
|
dec(Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
// Main program:
|
// Main program:
|
||||||
|
|
||||||
@ -45,16 +82,56 @@ int main(int argc, char *argv[])
|
|||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
argList::validArgs.insert("file .. fileN");
|
argList::validArgs.insert("file .. fileN");
|
||||||
|
|
||||||
|
argList::validOptions.insert("mask", "");
|
||||||
argList::validOptions.insert("count", "");
|
argList::validOptions.insert("count", "");
|
||||||
argList::validOptions.insert("info", "");
|
argList::validOptions.insert("info", "");
|
||||||
|
|
||||||
argList args(argc, argv, false, true);
|
argList args(argc, argv, false, true);
|
||||||
|
|
||||||
if (args.additionalArgs().empty())
|
|
||||||
|
if (args.optionFound("mask"))
|
||||||
|
{
|
||||||
|
Info<< "bit width: " << unsigned(sizeof(unsigned)*CHAR_BIT) << endl;
|
||||||
|
reportInfo<1>();
|
||||||
|
reportInfo<2>();
|
||||||
|
reportInfo<3>();
|
||||||
|
reportInfo<4>();
|
||||||
|
reportInfo<5>();
|
||||||
|
reportInfo<6>();
|
||||||
|
reportInfo<7>();
|
||||||
|
reportInfo<8>();
|
||||||
|
reportInfo<9>();
|
||||||
|
reportInfo<10>();
|
||||||
|
reportInfo<11>();
|
||||||
|
reportInfo<12>();
|
||||||
|
reportInfo<13>();
|
||||||
|
reportInfo<14>();
|
||||||
|
reportInfo<15>();
|
||||||
|
reportInfo<16>();
|
||||||
|
reportInfo<17>();
|
||||||
|
reportInfo<18>();
|
||||||
|
reportInfo<19>();
|
||||||
|
reportInfo<20>();
|
||||||
|
reportInfo<21>();
|
||||||
|
reportInfo<22>();
|
||||||
|
reportInfo<23>();
|
||||||
|
reportInfo<24>();
|
||||||
|
reportInfo<25>();
|
||||||
|
reportInfo<26>();
|
||||||
|
reportInfo<27>();
|
||||||
|
reportInfo<28>();
|
||||||
|
reportInfo<29>();
|
||||||
|
reportInfo<30>();
|
||||||
|
reportInfo<31>();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (args.additionalArgs().empty())
|
||||||
{
|
{
|
||||||
args.printUsage();
|
args.printUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
forAll(args.additionalArgs(), argI)
|
forAll(args.additionalArgs(), argI)
|
||||||
{
|
{
|
||||||
const string& srcFile = args.additionalArgs()[argI];
|
const string& srcFile = args.additionalArgs()[argI];
|
||||||
@ -62,6 +139,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
IFstream ifs(srcFile);
|
IFstream ifs(srcFile);
|
||||||
List<label> rawLst(ifs);
|
List<label> rawLst(ifs);
|
||||||
|
|
||||||
PackedBoolList packLst(rawLst);
|
PackedBoolList packLst(rawLst);
|
||||||
|
|
||||||
Info<< "size: " << packLst.size() << nl;
|
Info<< "size: " << packLst.size() << nl;
|
||||||
@ -72,11 +150,11 @@ int main(int argc, char *argv[])
|
|||||||
forAll(rawLst, elemI)
|
forAll(rawLst, elemI)
|
||||||
{
|
{
|
||||||
if (rawLst[elemI])
|
if (rawLst[elemI])
|
||||||
{
|
{
|
||||||
rawCount++;
|
rawCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< "raw count: " << rawCount << nl
|
Info<< "raw count: " << rawCount << nl
|
||||||
<< "packed count: " << packLst.count() << nl;
|
<< "packed count: " << packLst.count() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +162,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
packLst.print(Info);
|
packLst.print(Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl;
|
Info<< nl;
|
||||||
IOobject::writeDivider(Info);
|
IOobject::writeDivider(Info);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -204,19 +204,15 @@ Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
|
|||||||
template<unsigned nBits>
|
template<unsigned nBits>
|
||||||
Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << "PackedList<" << label(nBits) << ">"
|
const label packLen = packedLength(size_);
|
||||||
|
|
||||||
|
os << "PackedList<" << nBits << ">"
|
||||||
<< " max_value:" << max_value()
|
<< " max_value:" << max_value()
|
||||||
<< " packing:" << packing() << nl
|
<< " packing:" << packing() << nl
|
||||||
<< "values: " << size_ << "/" << capacity() << "( ";
|
<< " count: " << count() << nl
|
||||||
forAll(*this, i)
|
<< " size/capacity: " << size_ << "/" << capacity() << nl
|
||||||
{
|
<< " storage/capacity: " << packLen << "/" << StorageList::size()
|
||||||
os << get(i) << ' ';
|
<< "\n(\n";
|
||||||
}
|
|
||||||
|
|
||||||
label packLen = packedLength(size_);
|
|
||||||
|
|
||||||
os << ")\n"
|
|
||||||
<< "storage: " << packLen << "/" << StorageList::size() << "( ";
|
|
||||||
|
|
||||||
// mask value for complete segments
|
// mask value for complete segments
|
||||||
unsigned int mask = maskLower(packing());
|
unsigned int mask = maskLower(packing());
|
||||||
@ -240,7 +236,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int testBit = (1 << max_bits()); testBit; testBit >>= 1)
|
for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
|
||||||
{
|
{
|
||||||
if (mask & testBit)
|
if (mask & testBit)
|
||||||
{
|
{
|
||||||
@ -250,15 +246,15 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os << '0';
|
os << '-';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os << '.';
|
os << 'x';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout << ' ';
|
os << '\n';
|
||||||
}
|
}
|
||||||
os << ")\n";
|
os << ")\n";
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ inline unsigned int Foam::PackedList<nBits>::max_bits()
|
|||||||
template<unsigned nBits>
|
template<unsigned nBits>
|
||||||
inline unsigned int Foam::PackedList<nBits>::max_value()
|
inline unsigned int Foam::PackedList<nBits>::max_value()
|
||||||
{
|
{
|
||||||
return (1 << nBits) - 1;
|
return (1u << nBits) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +54,10 @@ inline unsigned int Foam::PackedList<nBits>::packing()
|
|||||||
template<unsigned nBits>
|
template<unsigned nBits>
|
||||||
inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset)
|
inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset)
|
||||||
{
|
{
|
||||||
return (1 << (nBits * offset)) - 1;
|
// return (1u << (nBits * offset)) - 1;
|
||||||
|
// The next one works more reliably with overflows
|
||||||
|
// eg, when compiled without optimization
|
||||||
|
return (~0u >> ( sizeof(StorageType)*CHAR_BIT - nBits * offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -581,7 +584,7 @@ inline void Foam::PackedList<nBits>::resize
|
|||||||
if (fill & ~max_value())
|
if (fill & ~max_value())
|
||||||
{
|
{
|
||||||
// overflow is max_value, fill everything
|
// overflow is max_value, fill everything
|
||||||
fill = ~0;
|
fill = ~0u;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -847,7 +850,7 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
|
|||||||
if (fill & ~max_value())
|
if (fill & ~max_value())
|
||||||
{
|
{
|
||||||
// treat overflow as max_value
|
// treat overflow as max_value
|
||||||
fill = ~0;
|
fill = ~0u;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user