Commit ceaaabab authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

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.
parent 70562ebf
/*
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
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment