Optimization updates

This commit is contained in:
2019-07-08 14:01:17 +02:00
parent 2f5d5ece47
commit 650bdc35bd
3 changed files with 84 additions and 21 deletions
+68 -9
View File
@@ -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<pair<string, uint64_t>> features_vector;
vector<pair<string, uint64_t>> 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<string, uint64_t>::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<string, uint64_t>::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<double> time_span = duration_cast<duration<double>>(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<double> time_span = duration_cast<duration<double>>(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);
}
}
}
+7 -2
View File
@@ -6,6 +6,7 @@
#include <climits>
#include <set>
#include <thread>
#include <mutex>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
@@ -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<pair<uint64_t, string>> 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<string, uint64_t> features[numDescriptors]; //array of maps that will hold the descriptors
map<string, uint64_t> mutatedFeatures[numDescriptors][numMutations];
vector<pair<string, uint64_t>> features_vector;
vector<pair<string, uint64_t>> mutatedFeatures_vector[numMutations];
vector<fs::Path> images;
multiset<pair<uint64_t, string> > distances; //multiset that stores the distances
};
+9 -10
View File
@@ -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;
}