Some performance hacks in nearest neighbor lookup. gives upto 10% of
speed on the single operation.
This commit is contained in:
parent
e6ce9d3d29
commit
1f381d790f
@ -53,6 +53,14 @@ static const unsigned MAX_CACHE_ELEMENTS = 1000;
|
||||
|
||||
namespace NNGrid{
|
||||
|
||||
struct IdenticalHashFunction {
|
||||
public:
|
||||
inline unsigned operator ()(const unsigned value) const {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static boost::thread_specific_ptr<std::ifstream> localStream;
|
||||
|
||||
template<bool WriteAccess = false>
|
||||
@ -149,34 +157,42 @@ public:
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
|
||||
double time1 = get_timestamp();
|
||||
bool foundNode = false;
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
|
||||
/** search for point on edge close to source */
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_GridEdge> candidates;
|
||||
double time2 = get_timestamp();
|
||||
boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > cellMap;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++){
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
|
||||
}
|
||||
}
|
||||
double time3 = get_timestamp();
|
||||
_GridEdge smallestEdge;
|
||||
_Coordinate tmp, newEndpoint;
|
||||
_Coordinate tmp;
|
||||
double dist = numeric_limits<double>::max();
|
||||
double time4 = get_timestamp();
|
||||
INFO("candidates.size(): " << candidates.size() );
|
||||
|
||||
double r, tmpDist;
|
||||
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
r = 0.;
|
||||
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
|
||||
//INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
|
||||
resultNode.Reset();
|
||||
dist = tmpDist;
|
||||
resultNode.edgeBasedNode = candidate.edgeBasedNode;
|
||||
resultNode.nodeBasedEdgeNameID = candidate.nameID;
|
||||
resultNode.weight1 = candidate.weight;
|
||||
dist = tmpDist;
|
||||
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
resultNode.weight2 = INT_MAX;
|
||||
resultNode.location.lat = tmp.lat;
|
||||
resultNode.location.lon = tmp.lon;
|
||||
foundNode = true;
|
||||
smallestEdge = candidate;
|
||||
newEndpoint = tmp;
|
||||
//} else if(tmpDist < dist) {
|
||||
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
|
||||
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs((int)candidate.edgeBasedNode-(int)resultNode.edgeBasedNode)) {
|
||||
@ -184,6 +200,9 @@ public:
|
||||
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
|
||||
}
|
||||
}
|
||||
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
|
||||
double time5 = get_timestamp();
|
||||
|
||||
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
|
||||
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
|
||||
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
|
||||
@ -193,23 +212,30 @@ public:
|
||||
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
|
||||
// }
|
||||
|
||||
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << ", newEndpoint: " << newEndpoint);
|
||||
double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, newEndpoint)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
|
||||
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << ", newEndpoint: " << newEndpoint);
|
||||
double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
|
||||
|
||||
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
|
||||
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
|
||||
//Hack to fix rounding errors and wandering via nodes.
|
||||
if(std::abs(location.lon - resultNode.location.lon) == 1)
|
||||
resultNode.location.lon = location.lon;
|
||||
if(std::abs(location.lat - resultNode.location.lat) == 1)
|
||||
resultNode.location.lat = location.lat;
|
||||
resultNode.location.lat = location.lat;
|
||||
|
||||
resultNode.weight1 *= ratio;
|
||||
if(INT_MAX != resultNode.weight2) {
|
||||
resultNode.weight2 -= resultNode.weight1;
|
||||
}
|
||||
resultNode.ratio = ratio;
|
||||
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
|
||||
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--");
|
||||
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
|
||||
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no") << "\n--");
|
||||
double time6 = get_timestamp();
|
||||
INFO("init1: " << (time2-time1)*1000);
|
||||
INFO("i/os: " << (time3-time2)*1000);
|
||||
INFO("init2: " << (time4-time3)*1000);
|
||||
INFO("mins: " << (time5-time4)*1000);
|
||||
INFO("rest: " << (time6-time5)*1000);
|
||||
INFO("compl: " << (time6-time1)*1000);
|
||||
return foundNode;
|
||||
}
|
||||
|
||||
@ -222,9 +248,10 @@ public:
|
||||
void FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
|
||||
unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
|
||||
std::vector<_GridEdge> candidates;
|
||||
boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > cellMap;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
|
||||
}
|
||||
}
|
||||
_Coordinate tmp;
|
||||
@ -245,9 +272,10 @@ public:
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
|
||||
std::vector<_GridEdge> candidates;
|
||||
boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > cellMap;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
|
||||
}
|
||||
}
|
||||
_Coordinate tmp;
|
||||
@ -265,18 +293,29 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned ,unsigned >& cellMap){
|
||||
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned, unsigned, IdenticalHashFunction >& cellMap){
|
||||
// double time1 = get_timestamp();
|
||||
unsigned lineBase = ramIndex/1024;
|
||||
lineBase = lineBase*32*32768;
|
||||
unsigned columnBase = ramIndex%1024;
|
||||
columnBase=columnBase*32;
|
||||
std::vector<std::pair<unsigned, unsigned> >insertionVector(1024);
|
||||
// double time2 = get_timestamp();
|
||||
for (int i = 0;i < 32;++i) {
|
||||
for (int j = 0;j < 32;++j) {
|
||||
unsigned fileIndex = lineBase + i * 32768 + columnBase + j;
|
||||
unsigned cellIndex = i * 32 + j;
|
||||
cellMap[fileIndex] = cellIndex;
|
||||
// cellMap[fileIndex] = cellIndex;
|
||||
insertionVector[i * 32 + j] = std::make_pair(fileIndex, cellIndex);
|
||||
}
|
||||
}
|
||||
// double time3 = get_timestamp();
|
||||
cellMap.insert(insertionVector.begin(), insertionVector.end());
|
||||
// double time4 = get_timestamp();
|
||||
|
||||
// INFO(" init: " << (time2-time1)*1000);
|
||||
// INFO(" vect: " << (time3-time2)*1000);
|
||||
// INFO(" inse: " << (time4-time3)*1000);
|
||||
}
|
||||
|
||||
inline bool DoubleEpsilonCompare(const double d1, const double d2) {
|
||||
@ -290,7 +329,7 @@ private:
|
||||
assert(indexOutFile.is_open());
|
||||
|
||||
vector<unsigned long> cellIndex(32*32,ULONG_MAX);
|
||||
boost::unordered_map< unsigned, unsigned > cellMap(1024);
|
||||
boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > cellMap(1024);
|
||||
|
||||
unsigned ramIndex = entriesWithSameRAMIndex.begin()->ramIndex;
|
||||
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
|
||||
@ -368,7 +407,7 @@ private:
|
||||
return counter;
|
||||
}
|
||||
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result) {
|
||||
inline void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result, boost::unordered_map< unsigned, unsigned, IdenticalHashFunction > & cellMap) {
|
||||
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
|
||||
unsigned long startIndexInFile = ramIndexTable[ramIndex];
|
||||
if(startIndexInFile == ULONG_MAX) {
|
||||
@ -377,7 +416,7 @@ private:
|
||||
|
||||
unsigned long cellIndex[32*32];
|
||||
|
||||
boost::unordered_map< unsigned, unsigned > cellMap(1024);
|
||||
cellMap.clear();
|
||||
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
|
||||
if(!localStream.get() || !localStream->is_open()) {
|
||||
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
|
||||
@ -389,11 +428,11 @@ private:
|
||||
|
||||
localStream->seekg(startIndexInFile);
|
||||
localStream->read((char*) cellIndex, 32*32*sizeof(unsigned long));
|
||||
assert(cellMap.find(fileIndex) != cellMap.end());
|
||||
if(cellIndex[cellMap.find(fileIndex)->second] == ULONG_MAX) {
|
||||
assert(cellMap.find(fileIndex) != cellMap.end());
|
||||
if(cellIndex[cellMap[fileIndex]] == ULONG_MAX) {
|
||||
return;
|
||||
}
|
||||
const unsigned long position = cellIndex[cellMap.find(fileIndex)->second] + 32*32*sizeof(unsigned long) ;
|
||||
const unsigned long position = cellIndex[cellMap[fileIndex]] + 32*32*sizeof(unsigned long) ;
|
||||
|
||||
localStream->seekg(position);
|
||||
_GridEdge gridEdge;
|
||||
@ -403,7 +442,7 @@ private:
|
||||
break;
|
||||
result.push_back(gridEdge);
|
||||
} while(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AddEdge(_GridEdge edge) {
|
||||
#ifndef ROUTED
|
||||
@ -505,10 +544,6 @@ private:
|
||||
return ramIndex;
|
||||
}
|
||||
|
||||
inline int signum(int x){
|
||||
return (x > 0) ? 1 : (x < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
const static unsigned long END_OF_BUCKET_DELIMITER = UINT_MAX;
|
||||
|
||||
ofstream indexOutFile;
|
||||
|
Loading…
Reference in New Issue
Block a user