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 "IFstream.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include <climits>
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@ -45,16 +82,56 @@ int main(int argc, char *argv[])
|
||||
argList::noParallel();
|
||||
argList::validArgs.insert("file .. fileN");
|
||||
|
||||
argList::validOptions.insert("mask", "");
|
||||
argList::validOptions.insert("count", "");
|
||||
argList::validOptions.insert("info", "");
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
forAll(args.additionalArgs(), argI)
|
||||
{
|
||||
const string& srcFile = args.additionalArgs()[argI];
|
||||
@ -62,6 +139,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
IFstream ifs(srcFile);
|
||||
List<label> rawLst(ifs);
|
||||
|
||||
PackedBoolList packLst(rawLst);
|
||||
|
||||
Info<< "size: " << packLst.size() << nl;
|
||||
@ -72,11 +150,11 @@ int main(int argc, char *argv[])
|
||||
forAll(rawLst, elemI)
|
||||
{
|
||||
if (rawLst[elemI])
|
||||
{
|
||||
{
|
||||
rawCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Info<< "raw count: " << rawCount << nl
|
||||
Info<< "raw count: " << rawCount << nl
|
||||
<< "packed count: " << packLst.count() << nl;
|
||||
}
|
||||
|
||||
@ -84,7 +162,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
packLst.print(Info);
|
||||
}
|
||||
|
||||
|
||||
Info<< nl;
|
||||
IOobject::writeDivider(Info);
|
||||
}
|
||||
|
||||
@ -204,19 +204,15 @@ Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
|
||||
template<unsigned nBits>
|
||||
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()
|
||||
<< " packing:" << packing() << nl
|
||||
<< "values: " << size_ << "/" << capacity() << "( ";
|
||||
forAll(*this, i)
|
||||
{
|
||||
os << get(i) << ' ';
|
||||
}
|
||||
|
||||
label packLen = packedLength(size_);
|
||||
|
||||
os << ")\n"
|
||||
<< "storage: " << packLen << "/" << StorageList::size() << "( ";
|
||||
<< " count: " << count() << nl
|
||||
<< " size/capacity: " << size_ << "/" << capacity() << nl
|
||||
<< " storage/capacity: " << packLen << "/" << StorageList::size()
|
||||
<< "\n(\n";
|
||||
|
||||
// mask value for complete segments
|
||||
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)
|
||||
{
|
||||
@ -250,15 +246,15 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
||||
}
|
||||
else
|
||||
{
|
||||
os << '0';
|
||||
os << '-';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os << '.';
|
||||
os << 'x';
|
||||
}
|
||||
}
|
||||
cout << ' ';
|
||||
os << '\n';
|
||||
}
|
||||
os << ")\n";
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ inline unsigned int Foam::PackedList<nBits>::max_bits()
|
||||
template<unsigned nBits>
|
||||
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>
|
||||
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())
|
||||
{
|
||||
// overflow is max_value, fill everything
|
||||
fill = ~0;
|
||||
fill = ~0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -847,7 +850,7 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
|
||||
if (fill & ~max_value())
|
||||
{
|
||||
// treat overflow as max_value
|
||||
fill = ~0;
|
||||
fill = ~0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user