Moving XOR-FastHash to its own File
This commit is contained in:
parent
7194fe02d1
commit
e29b19805c
@ -31,16 +31,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "../DataStructures/BinaryHeap.h"
|
||||||
#include "../DataStructures/DeallocatingVector.h"
|
#include "../DataStructures/DeallocatingVector.h"
|
||||||
#include "../DataStructures/DynamicGraph.h"
|
#include "../DataStructures/DynamicGraph.h"
|
||||||
#include "../DataStructures/Percent.h"
|
#include "../DataStructures/Percent.h"
|
||||||
#include "../DataStructures/BinaryHeap.h"
|
#include "../DataStructures/XORFastHash.h"
|
||||||
#include "../Util/OpenMPReplacement.h"
|
#include "../Util/OpenMPReplacement.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
|
|
||||||
|
|
||||||
#include <valgrind/callgrind.h>
|
|
||||||
|
|
||||||
class Contractor {
|
class Contractor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -96,26 +94,6 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class XORFastHash {
|
|
||||||
std::vector<unsigned char> table1;
|
|
||||||
std::vector<unsigned char> table2;
|
|
||||||
public:
|
|
||||||
XORFastHash() {
|
|
||||||
table1.resize(1 << 16);
|
|
||||||
table2.resize(1 << 16);
|
|
||||||
for(unsigned i = 0; i < (1 << 16); ++i) {
|
|
||||||
table1[i] = i; table2[i];
|
|
||||||
}
|
|
||||||
std::random_shuffle(table1.begin(), table1.end());
|
|
||||||
std::random_shuffle(table2.begin(), table2.end());
|
|
||||||
}
|
|
||||||
unsigned short operator()(const unsigned originalValue) const {
|
|
||||||
unsigned short lsb = ((originalValue-1) & 0xffff);
|
|
||||||
unsigned short msb = (((originalValue-1) >> 16) & 0xffff);
|
|
||||||
return table1[lsb] ^ table2[msb];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template<class ContainerT >
|
template<class ContainerT >
|
||||||
@ -227,7 +205,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Run() {
|
void Run() {
|
||||||
CALLGRIND_START_INSTRUMENTATION;
|
|
||||||
const NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
const NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||||
Percent p (numberOfNodes);
|
Percent p (numberOfNodes);
|
||||||
|
|
||||||
@ -446,7 +423,6 @@ public:
|
|||||||
|
|
||||||
p.printStatus(numberOfContractedNodes);
|
p.printStatus(numberOfContractedNodes);
|
||||||
}
|
}
|
||||||
CALLGRIND_STOP_INSTRUMENTATION;
|
|
||||||
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
|
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
|
||||||
delete threadData[threadNum];
|
delete threadData[threadNum];
|
||||||
}
|
}
|
||||||
@ -562,18 +538,18 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node){
|
float _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node){
|
||||||
_ContractionInformation stats;
|
_ContractionInformation stats;
|
||||||
|
|
||||||
//perform simulated contraction
|
//perform simulated contraction
|
||||||
_Contract< true> ( data, node, &stats );
|
_Contract< true> ( data, node, &stats );
|
||||||
|
|
||||||
// Result will contain the priority
|
// Result will contain the priority
|
||||||
double result;
|
float result;
|
||||||
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
|
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
|
||||||
result = 1 * nodeData->depth;
|
result = 1 * nodeData->depth;
|
||||||
else
|
else
|
||||||
result = 2 * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + 4 * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + 1 * nodeData->depth;
|
result = 2 * ((( float ) stats.edgesAdded ) / stats.edgesDeleted ) + 4 * ((( float ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + 1 * nodeData->depth;
|
||||||
assert( result >= 0 );
|
assert( result >= 0 );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -763,21 +739,21 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool bias(const NodeID a, const NodeID b) {
|
|
||||||
|
/**
|
||||||
|
* This bias function takes up 22 assembly instructions in total on X86
|
||||||
|
*/
|
||||||
|
inline bool bias(const NodeID a, const NodeID b) const {
|
||||||
unsigned short hasha = fastHash(a);
|
unsigned short hasha = fastHash(a);
|
||||||
unsigned short hashb = fastHash(b);
|
unsigned short hashb = fastHash(b);
|
||||||
|
|
||||||
//Decision with branching
|
//The compiler optimizes that to conditional register flags but without branching statements!
|
||||||
// if(hasha != hashb)
|
if(hasha != hashb)
|
||||||
// return hasha < hashb;
|
return hasha < hashb;
|
||||||
// return a < b;
|
return a < b;
|
||||||
|
|
||||||
//Decision without branching
|
|
||||||
return (hasha < hashb)+((hasha==hashb)*(a<b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<_DynamicGraph> _graph;
|
boost::shared_ptr<_DynamicGraph> _graph;
|
||||||
|
67
DataStructures/XORFastHash.h
Normal file
67
DataStructures/XORFastHash.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
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 FASTXORHASH_H_
|
||||||
|
#define FASTXORHASH_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is an implementation of Tabulation hashing, which has suprising properties like universality.
|
||||||
|
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
|
||||||
|
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
|
||||||
|
|
||||||
|
1: movq table2(%rip), %rdx
|
||||||
|
2: movl %edi, %eax
|
||||||
|
3: movzwl %di, %edi
|
||||||
|
4: shrl $16, %eax
|
||||||
|
5: movzwl %ax, %eax
|
||||||
|
6: movzbl (%rdx,%rax), %eax
|
||||||
|
7: movq table1(%rip), %rdx
|
||||||
|
8: xorb (%rdx,%rdi), %al
|
||||||
|
9: movzbl %al, %eax
|
||||||
|
10: ret
|
||||||
|
|
||||||
|
*/
|
||||||
|
class XORFastHash {
|
||||||
|
std::vector<unsigned char> table1;
|
||||||
|
std::vector<unsigned char> table2;
|
||||||
|
public:
|
||||||
|
XORFastHash() {
|
||||||
|
table1.resize(1 << 16);
|
||||||
|
table2.resize(1 << 16);
|
||||||
|
for(unsigned i = 0; i < (1 << 16); ++i) {
|
||||||
|
table1[i] = i; table2[i];
|
||||||
|
}
|
||||||
|
std::random_shuffle(table1.begin(), table1.end());
|
||||||
|
std::random_shuffle(table2.begin(), table2.end());
|
||||||
|
}
|
||||||
|
unsigned short operator()(const unsigned originalValue) const {
|
||||||
|
unsigned short lsb = ((originalValue) & 0xffff);
|
||||||
|
unsigned short msb = (((originalValue) >> 16) & 0xffff);
|
||||||
|
return table1[lsb] ^ table2[msb];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FASTXORHASH_H_ */
|
Loading…
Reference in New Issue
Block a user