diff --git a/Algorithms/IteratorBasedCRC32.h b/Algorithms/IteratorBasedCRC32.h new file mode 100644 index 000000000..7e23a0edb --- /dev/null +++ b/Algorithms/IteratorBasedCRC32.h @@ -0,0 +1,110 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program 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 Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. + */ + + +#ifndef ITERATORBASEDCRC32_H_ +#define ITERATORBASEDCRC32_H_ + +#include // for boost::crc_32_type +#include + +template +class IteratorbasedCRC32 { +private: + typedef typename ContainerT::iterator ContainerT_iterator; + unsigned crc; + unsigned slowcrc_table[1<<8]; + + typedef boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> my_crc_32_type; + typedef unsigned (IteratorbasedCRC32::*CRC32CFunctionPtr)(char *str, unsigned len, unsigned crc); + + unsigned SoftwareBasedCRC32(char *str, unsigned len, unsigned crc){ + boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> CRC32_Processor; + CRC32_Processor.process_bytes( str, len); + return CRC32_Processor.checksum(); + } + unsigned SSEBasedCRC32( char *str, unsigned len, unsigned crc){ + unsigned q=len/sizeof(unsigned), + r=len%sizeof(unsigned), + *p=(unsigned*)str/*, crc*/; + + //crc=0; + while (q--) { + __asm__ __volatile__( + ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;" + :"=S"(crc) + :"0"(crc), "c"(*p) + ); + ++p; + } + + str=(char*)p; + while (r--) { + __asm__ __volatile__( + ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;" + :"=S"(crc) + :"0"(crc), "c"(*str) + ); + ++str; + } + return crc; + } + + unsigned cpuid(unsigned functionInput){ + unsigned eax; + unsigned ebx; + unsigned ecx; + unsigned edx; + asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (functionInput)); + return ecx; + } + + CRC32CFunctionPtr detectBestCRC32C(){ + static const int SSE42_BIT = 20; + unsigned ecx = cpuid(1); + bool hasSSE42 = ecx & (1 << SSE42_BIT); + if (hasSSE42) { + std::cout << "using hardware base sse computation" << std::endl; + return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated; + } else { + std::cout << "using software base sse computation" << std::endl; + return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; + } + } + CRC32CFunctionPtr crcFunction; +public: + IteratorbasedCRC32(): crc(0) { + crcFunction = detectBestCRC32C(); + } + + virtual ~IteratorbasedCRC32() {}; + + unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) { + unsigned crc = 0; + while(iter != end) { + char * data = (char*)&(*iter); + crc =((*this).*(crcFunction))(data, sizeof(typename ContainerT::value_type*), crc); + ++iter; + } + return crc; + } +}; + +#endif /* ITERATORBASEDCRC32_H_ */ diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 278a270d8..b94bb11f7 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -42,7 +42,7 @@ extern "C" { #include #include -#include "Algorithms/CRC32.h" +#include "Algorithms/IteratorBasedCRC32.h" #include "Util/OpenMPWrapper.h" #include "typedefs.h" #include "Contractor/Contractor.h" @@ -201,9 +201,10 @@ int main (int argc, char *argv[]) { WritableGrid * writeableGrid = new WritableGrid(); writeableGrid->ConstructGrid(nodeBasedEdgeList, ramIndexOut, fileIndexOut); delete writeableGrid; - CRC32 crc32; - unsigned crc32OfNodeBasedEdgeList = crc32((char *)&(nodeBasedEdgeList[0]), nodeBasedEdgeList.size()*sizeof(EdgeBasedGraphFactory::EdgeBasedNode)); + IteratorbasedCRC32 > crc32; + unsigned crc32OfNodeBasedEdgeList = crc32(nodeBasedEdgeList.begin(), nodeBasedEdgeList.end() ); nodeBasedEdgeList.clear(); + INFO("CRC32 based checksum is " << crc32OfNodeBasedEdgeList); /*** * Contracting the edge-expanded graph