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:
Mark Olesen
2009-07-23 22:46:52 +02:00
committed by andy
parent 70562ebf80
commit ceaaabab56
4 changed files with 108 additions and 24 deletions

View File

@ -0,0 +1,7 @@
/*
check for consistent behaviour with non-optimized code
*/
EXE_INC = \
-DFULLDEBUG -g -O0

View File

@ -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);
} }

View File

@ -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";

View File

@ -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
{ {