From 650bdc35bd0cf9a4649d2ddac5688b95d948380d Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Mon, 8 Jul 2019 14:01:17 +0200 Subject: [PATCH] Optimization updates --- DescriptorManager.cpp | 77 ++++++++++++++++++++++++++++++++++++++----- DescriptorManager.h | 9 +++-- main.cpp | 19 +++++------ 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/DescriptorManager.cpp b/DescriptorManager.cpp index 1befc0c..31dbe67 100644 --- a/DescriptorManager.cpp +++ b/DescriptorManager.cpp @@ -58,11 +58,12 @@ DescriptorManager::DescriptorManager(const fs::path & image_path) { //Returns a pointer to the image mutated by the given method. //Either gets it from disk, or calculates it directly. Image* DescriptorManager::GetMutated(Image* image, string image_name, int method) { + return mutators[method]->getMutated(image); fs::path mutPath(img_path / mutators[method]->ToPath() / image_name); Image* mutated; if (!fs::exists(mutPath)) { //only mutate if nothing on disk mutated = mutators[method]->getMutated(image); - mutated->write(mutPath.generic_string()); + //mutated->write(mutPath.generic_string()); } else { mutated = new Image; @@ -78,7 +79,7 @@ void DescriptorManager::LoadFeatures(string image_path, string image_name) { if (features[i].count(image_name) > 0) { continue; } - current_image = new Image(image_path); + if(!current_image) current_image = new Image(image_path); fs::path featurePath("meta" / descriptor_types[i]->ToPath() / image_name); uint64_t b1; @@ -152,10 +153,39 @@ void DescriptorManager::Init() { } } +//Check which of the features we loaded from disk +//skips checking all images we already have. +//If only one part is missing, we mark the image for recalculation +void DescriptorManager::CompareFeatures() { + vector> features_vector; + vector> mutatedFeatures_vector[numMutations]; + for (fs::directory_iterator itr(img_path); itr != fs::directory_iterator(); ++itr) { + if (!itr->path().has_extension()) continue; //skip directories and such + string image_name = itr->path().filename().generic_string(); + { //Progress bar + filecount++; + cout << setw(60) << setfill('*') << "\r" << string(60, ' ') << flush; + cout << setfill('*') << setw(60) << right<< "\rChecking which images we already have: " << filecount*100/numImages << "% - (" << filecount << "/" << numImages << "): " << image_name << flush; + } + + for (int method = 0; method < numDescriptors; i++) { + bool load = false; + if (features[method].count(image_name) == 0) { + load = true; + } + for (int mutation = 0; !load && mutation < numMutations; mutation++) { + if (mutatedFeatures[method][mutation].count(image_name) == 0) { + load = true; + } + } + if (load) images.push_back(itr->path()); + } + } +} //Saves feature map to disk. void DescriptorManager::SaveToDisk() { - { //Boost serialization + { //TODO: make backups first. ofstream f("features.map", ios::binary); ar::binary_oarchive oa(f); oa << features; @@ -254,12 +284,41 @@ void DescriptorManager::runExperiments() { } //Test post please ignore -void DescriptorManager::test() { - const uint64_t n = 1000000000; - //string insert = "constant"; //assuming string value doesn't matter. - int method = 2; +void DescriptorManager::test(int method) { + //for (int method = 0; method < numDescriptors; method++) { //paralellized { + high_resolution_clock::time_point t1 = high_resolution_clock::now(); + //foreach image + for (map::iterator img = features[method].begin(); img != features[method].end(); ++img) { + uint64_t targets[numMutations]; + uint64_t better_counts[numMutations]; + for (int i = 0; i < numMutations; i++) { + targets[i] = descriptor_types[method]->distance(img->second, mutatedFeatures[method][i][img->first]); + better_counts[i] = 0; + } + for (map::iterator it = features[method].begin(); it != features[method].end(); ++it) { + uint64_t distance = descriptor_types[method]->distance(img->second, it->second); + for (int i = 0; i < numMutations; i++) + { + if(distance >= targets[i]) better_counts[i]++; + } + } + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); + duration time_span = duration_cast>(t2 - t1); + //mu.lock(); + cout << "It took me " << time_span.count() << " seconds to rank one image with " << numImages << " images." << endl; + //mu.unlock(); + } + + + + + + /*{ + + const uint64_t n = 1000000000; high_resolution_clock::time_point t1 = high_resolution_clock::now(); int target_distance = 5; uint64_t better_count = 0; @@ -273,7 +332,7 @@ void DescriptorManager::test() { high_resolution_clock::time_point t2 = high_resolution_clock::now(); duration time_span = duration_cast>(t2 - t1); cout << "It took me " << time_span.count() << " seconds to sort " << n << " big numbers." << endl; - } + }*/ } @@ -324,4 +383,4 @@ void DescriptorManager::generatePreviews(string imagename) { for (int i = 0; i < numDescriptors; i++) { descriptor_types[i]->preview(img); } -} \ No newline at end of file +} diff --git a/DescriptorManager.h b/DescriptorManager.h index 15bb26f..bc8bd17 100644 --- a/DescriptorManager.h +++ b/DescriptorManager.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -43,12 +44,13 @@ public: void LoadMutationFeatures(string image_path, string image_name, int mutation); Image* GetMutated(Image* image, string image_name, int method); void Init(); + void CompareFeatures() void SaveToDisk(); void LoadFromDisk(); void rankImages(string image_name, int method); multiset> rankMutations(string image_name, int method); void runExperiments(); - void test(); + void test(int method); void generatePreviews(string imagename); void outputMap(int a); void outputMap(); @@ -56,16 +58,19 @@ public: private: fs::path img_path; int numImages; - static const int numDescriptors = 8; static const int numMutations = 8; Descriptor* descriptor_types[numDescriptors]; Mutation* mutators[numMutations]; + //mutex mu; //for threading and suchlikes Image* current_image = NULL; //for caching purposes //TODO: Are maps the best container for us? Logarithmic random access is bad, but otherwise it might be fine? map features[numDescriptors]; //array of maps that will hold the descriptors map mutatedFeatures[numDescriptors][numMutations]; + vector> features_vector; + vector> mutatedFeatures_vector[numMutations]; + vector images; multiset > distances; //multiset that stores the distances }; diff --git a/main.cpp b/main.cpp index 7878728..f63e041 100644 --- a/main.cpp +++ b/main.cpp @@ -26,21 +26,20 @@ int main(int argc, char **argv) { cout << "Continuing.." << endl; } InitializeMagick(*argv); - DescriptorManager* manager = new DescriptorManager("test"); + DescriptorManager* manager = new DescriptorManager("data"); manager->Init();/* manager->rankImages(imagename, method); manager->outputRank(imagename, method); manager->outputMap(method);*/ cout << endl; - - cout << "Starting first compute thread.." << endl; - thread first(&DescriptorManager::test, manager); - cout << "Starting second computer thread.." << endl; - thread second(&DescriptorManager::test, manager); - first.join(); - - second.join(); - cout << "we done." << endl; + const int thread_count = 8; + thread* thrds[thread_count]; + for (int i =0; i < thread_count; i++) { + thrds[i] = new thread(&DescriptorManager::test, manager, i); + } + for (int i =0; i < thread_count; i++) { + thrds[i]->join(); + } //manager->test(); return 0; }