From 84ec272d23ef5ad209cc9dc69754c5e5a5b7e80b Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 26 Jan 2009 00:33:28 +0100 Subject: [PATCH 01/13] PackedList changes - added Mattijs' speed tests - optimized resize() and assignment operators to avoid set() method - add const_iterator and re-did the proxy handling. Reading/writing by looping across iterators is still somewhat slow, but might be acceptable. --- applications/test/PackedList/PackedListTest.C | 39 +- applications/test/PackedList2/Make/files | 3 + applications/test/PackedList2/Make/options | 0 .../test/PackedList2/PackedListTest2.C | 337 ++++++++++++++++++ .../containers/Lists/PackedList/PackedList.C | 44 ++- .../containers/Lists/PackedList/PackedList.H | 174 ++++++--- .../containers/Lists/PackedList/PackedListI.H | 337 +++++++++++++----- 7 files changed, 774 insertions(+), 160 deletions(-) create mode 100644 applications/test/PackedList2/Make/files create mode 100644 applications/test/PackedList2/Make/options create mode 100644 applications/test/PackedList2/PackedListTest2.C diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C index b00c703a37..62bf38d521 100644 --- a/applications/test/PackedList/PackedListTest.C +++ b/applications/test/PackedList/PackedListTest.C @@ -46,11 +46,11 @@ int main(int argc, char *argv[]) list1.print(Info); Info<< "\ntest assign uniform value\n"; - list1 = 2; + list1 = 4; list1.print(Info); Info<< "\ntest resize with value (without reallocation)\n"; - list1.resize(6, 3); + list1.resize(8, list1.max_value()); list1.print(Info); Info<< "\ntest set() function\n"; @@ -96,7 +96,7 @@ int main(int argc, char *argv[]) list1.print(Info); Info<< "\ntest setCapacity() operation\n"; - list1.setCapacity(30); + list1.setCapacity(100); list1.print(Info); Info<< "\ntest operator[] assignment\n"; @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) list1.print(Info); Info<< "\ntest setCapacity smaller\n"; - list1.setCapacity(32); + list1.setCapacity(24); list1.print(Info); // add in some misc values @@ -118,7 +118,7 @@ int main(int argc, char *argv[]) Info<< "\ntest iterator\n"; PackedList<3>::iterator iter = list1.begin(); - Info<< "iterator:" << iter() << "\n"; + Info<< "begin():"; iter.print(Info) << "\n"; Info<< "\ntest iterator operator=\n"; @@ -131,23 +131,29 @@ int main(int argc, char *argv[]) list1.print(Info); Info<< "\ntest get() method\n"; - Info<< "get(10):" << list1.get(10) - << " and list[10]:" << unsigned(list1[10]) << "\n"; + Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n"; list1.print(Info); Info<< "\ntest iterator indexing\n"; - Info<< "end() "; - list1.end().print(Info) << "\n"; + Info<< "cend() "; + list1.cend().print(Info) << "\n"; - for (iter = list1[31]; iter != list1.end(); ++iter) + for + ( + PackedList<3>::const_iterator cit = list1[30]; + cit != list1.cend(); + ++cit) { - iter.print(Info); + cit.print(Info); } Info<< "\ntest operator[] auto-vivify\n"; const unsigned int val = list1[45]; Info<< "list[45]:" << val << "\n"; + list1[45] = list1.max_value(); + Info<< "list[45]:" << list1[45] << "\n"; + list1[49] = list1.max_value(); list1.print(Info); @@ -161,8 +167,15 @@ int main(int argc, char *argv[]) Info<< "\ntest pattern that fills all bits\n"; PackedList<4> list3(8, 8); - list3[list3.size()-2] = 0; - list3[list3.size()-1] = list3.max_value(); + + label pos = list3.size() - 1; + + list3[pos--] = list3.max_value(); + list3[pos--] = 0; + list3[pos--] = list3.max_value(); + list3.print(Info); + + Info<< "removed final value: " << list3.remove() << endl; list3.print(Info); Info<< "\n\nDone.\n"; diff --git a/applications/test/PackedList2/Make/files b/applications/test/PackedList2/Make/files new file mode 100644 index 0000000000..bb1f3085fa --- /dev/null +++ b/applications/test/PackedList2/Make/files @@ -0,0 +1,3 @@ +PackedListTest2.C + +EXE = $(FOAM_USER_APPBIN)/PackedListTest2 diff --git a/applications/test/PackedList2/Make/options b/applications/test/PackedList2/Make/options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/applications/test/PackedList2/PackedListTest2.C b/applications/test/PackedList2/PackedListTest2.C new file mode 100644 index 0000000000..ed86a0778a --- /dev/null +++ b/applications/test/PackedList2/PackedListTest2.C @@ -0,0 +1,337 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Application + +Description + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "boolList.H" +#include "PackedBoolList.H" +#include "HashSet.H" +#include "cpuTime.H" +#include + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +// Main program: + +int main(int argc, char *argv[]) +{ + const label n = 1000000; + const label nIters = 1000; + + unsigned int sum = 0; + + PackedBoolList packed(n, 1); + boolList unpacked(n, true); + std::vector stlVector(n, true); + + labelHashSet emptyHash; + labelHashSet fullHash; + for(label i = 0; i < n; i++) + { + fullHash.insert(i); + } + + cpuTime timer; + + for (label iter = 0; iter < nIters; iter++) + { + packed.resize(40); + packed.shrink(); + packed.resize(n, 1); + } + Info<< "resize/shrink/resize:" << timer.cpuTimeIncrement() << " s\n\n"; + + // Dummy addition + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(unpacked, i) + { + sum += i + 1; + } + } + Info<< "Dummy loop:" << timer.cpuTimeIncrement() << " s" << endl; + Info<< " sum " << sum << endl; + + // + // Read + // + + // Read stl + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + for(unsigned int i = 0; i < stlVector.size(); i++) + { + sum += stlVector[i]; + } + } + Info<< "Reading stl:" << timer.cpuTimeIncrement() << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read unpacked + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(unpacked, i) + { + sum += unpacked[i]; + } + } + Info<< "Reading unpacked:" << timer.cpuTimeIncrement() << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read packed + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + sum += packed.get(i); + } + } + Info<< "Reading packed using get:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read packed + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + sum += packed[i]; + } + } + Info<< "Reading packed using reference:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read via iterator + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + for + ( + PackedBoolList::iterator it = packed.begin(); + it != packed.end(); + ++it + ) + { + sum += it; + } + } + Info<< "Reading packed using iterator:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read via iterator + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + for + ( + PackedBoolList::const_iterator cit = packed.cbegin(); + cit != packed.cend(); + ++cit + ) + { + sum += cit(); + } + } + Info<< "Reading packed using const_iterator():" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read empty hash + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + sum += emptyHash.found(i); + } + } + Info<< "Reading empty labelHashSet:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + // Read full hash + sum = 0; + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + sum += fullHash.found(i); + } + } + Info<< "Reading full labelHashSet:" << timer.cpuTimeIncrement() + << " s" << endl; + Info<< " sum " << sum << endl; + + + + // + // Write + // + + // Write stl + for (label iter = 0; iter < nIters; iter++) + { + for (unsigned int i = 0; i < stlVector.size(); i++) + { + stlVector[i] = true; + } + } + Info<< "Writing stl:" << timer.cpuTimeIncrement() << " s" << endl; + + // Write unpacked + for (label iter = 0; iter < nIters; iter++) + { + forAll(unpacked, i) + { + unpacked[i] = true; + } + } + Info<< "Writing unpacked:" << timer.cpuTimeIncrement() << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + packed[i] = 1; + } + } + Info<< "Writing packed using reference:" << timer.cpuTimeIncrement() + << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + forAll(packed, i) + { + packed.set(i, 1); + } + } + Info<< "Writing packed using set:" << timer.cpuTimeIncrement() + << " s" << endl; + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + for + ( + PackedBoolList::iterator it = packed.begin(); + it != packed.end(); + ++it + ) + { + it = 1; + } + } + Info<< "Writing packed using iterator:" << timer.cpuTimeIncrement() + << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + for + ( + PackedBoolList::iterator it = packed.begin(); + it != packed.end(); + ++it + ) + { + it() = 1; + } + } + Info<< "Writing packed using iteratorRef:" << timer.cpuTimeIncrement() + << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + packed = 0; + } + Info<< "Writing packed uniform 0:" << timer.cpuTimeIncrement() + << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + packed = 1; + } + Info<< "Writing packed uniform 1:" << timer.cpuTimeIncrement() + << " s" << endl; + + + PackedList<3> oddPacked(n, 3); + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + packed = 0; + } + Info<< "Writing packed<3> uniform 0:" << timer.cpuTimeIncrement() + << " s" << endl; + + + // Write packed + for (label iter = 0; iter < nIters; iter++) + { + packed = 1; + } + Info<< "Writing packed<3> uniform 1:" << timer.cpuTimeIncrement() + << " s" << endl; + + + + Info << "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C index d4bb3ca826..9e7f0de14a 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C @@ -67,10 +67,11 @@ Foam::labelList Foam::PackedList::values() const template -Foam::Ostream& Foam::PackedList::iterator::print(Ostream& os) const +Foam::Ostream& Foam::PackedList::const_iterator::print(Ostream& os) const { - os << "iterator<" << nBits << "> [" << position() << "]" - << " elem:" << elem_ << " offset:" << offset_ + os << "iterator<" << nBits << "> [" + << (index_ * packing() + offset_) << "]" + << " index:" << index_ << " offset:" << offset_ << " value:" << unsigned(*this) << nl; @@ -90,27 +91,41 @@ Foam::Ostream& Foam::PackedList::print(Ostream& os) const os << get(i) << ' '; } + label packLen = packedLength(size()); + os << ")\n" - << "storage: " << storage().size() << "( "; + << "storage: " << packLen << "/" << storage().size() << "( "; - label count = size(); + // mask for the valid bits + unsigned int validBits = max_value(); + for (unsigned int i = 1; i < packing(); ++i) + { + validBits |= (validBits << nBits); + } - forAll(storage(), i) + for (label i=0; i < packLen; i++) { const PackedStorage& rawBits = storage()[i]; - // create mask for unaddressed bits - unsigned int addressed = 0; - - for (unsigned packI = 0; count && packI < packing(); packI++, count--) + // the final storage may not be full, modify validBits accordingly + if (i+1 == packLen) { - addressed <<= nBits; - addressed |= max_value(); + label junk = size() % packing(); + + if (junk) + { + junk = packing() - junk; + } + + for (label j=0; j < junk; j++) + { + validBits >>= nBits; + } } for (unsigned int testBit = 0x1 << max_bits(); testBit; testBit >>= 1) { - if (testBit & addressed) + if (testBit & validBits) { if (rawBits & testBit) { @@ -123,7 +138,7 @@ Foam::Ostream& Foam::PackedList::print(Ostream& os) const } else { - os << '_'; + os << '.'; } } cout << ' '; @@ -156,7 +171,6 @@ void Foam::PackedList::operator=(const UList