Objektorientiert und OpenMP?
-
Hey Leute, ich habe da ein kleines Problem. Ich soll ein Programm schreiben das einen String-Matching Algorithmus implementiert. Es handelt sich um den Horspool falls das was sagt/hilft. Ich habe den Horspool Objektorientiert angelegt und er läuft auch Problemlos. Wobei ich glaube das er ein wenig langsam ist. Nun soll das ganze mit OMP Parallel programmiert werden. Aber irgendwie will das Programm nicht ganz so wie ich will. Ich dachte mir, ich teile die Datei in der das Pattern gesucht werden soll in die Anzahl von Teilen, wie ich Threads erstellen möchte. Jeder Teil der Datei(Thread) ist ein eigenes Objekt. Dann rufe ich über eine for-Schleife für jedes Objekt eine Funktion des Objektes auf in der der Horspool eigentlich durchgeführt wird. Allerdings will das ganze einfach nicht parallel laufen. Ich bekomme immer die gleiche Zeit. Könnt ihr mir bitte helfen?
Ich hänge euch mal meinen Code mit an.#include <stdio.h> #include <string.h> #include <stdlib.h> #include <vector> #include <algorithm> #include <iostream> #include <fstream> #include <map> #include <omp.h> using namespace std; ifstream::pos_type size; //For Horspool class Search { static const int MAXCHAR = 256; map<char,int> d; int m; char* patt; int count; vector<int>hits ; public: Search(char*); int find(char*,int,int); int get_count(); vector<int> get_hits(); }; int Search::get_count() { return count; } vector <int> Search::get_hits() { return hits; } Search::Search(char* p) { count = 0; patt = p; m = strlen(patt); int k = 0; for (k = 0; k < MAXCHAR; k++) d[k] = m; for (k = 0; k < m - 1; k++){ if(d.find(patt[k])==d.end()||d[patt[k]]>m-k-1) d[patt[k]] = m - k - 1; } } int Search::find(char* text,int start,int end) { if(start>0) start +=1; int n =end; if (m > end-start) return 0; int k = start+(m - 1); while (k < n) { int j = m - 1; int i = k; while (j >= 0 && text[i] == patt[j]) { j--; i--; } if (j < 0) { hits.push_back(i + 1); count++; } k += d[text[k]]; } return 0; } //Load File bool loadText(vector<char> &text, char* fileName) { // open file in binary and read-only mode // and set file pointer to the end ifstream file(fileName, ios::in | ios::binary | ios::ate); if (!file.is_open()) return false; // file pointer position is equal to file size // ifstream::pos_type size = file.tellg(); // resize string buffer text.resize(size); // go to file begin and read complete file file.seekg(0, ios::beg); file.read(&text[0], size); file.close(); return true; } bool createFile(vector<int> &hits, char* filename ){ ofstream outfile; outfile.open(filename, ios::out | ios::trunc); if(!outfile.is_open()) return false; for(int i=0; i<hits.size(); ++i) outfile << (hits[i])<<endl; outfile.close(); return true; } int main(int argc, char *argv[]) { if (argc < 5) { cerr << argv[0] << " <TEXTFILE> <PATTERN 1> <NMBR OF THREADS> <OUTPUTFILE>" << endl; return 0; } vector<char> text; if (!loadText(text, argv[1])) { cerr << "Could not open text file." << endl; return 1; } vector<Search*> SearchObjects; int nmbr_of_threads = atoi(argv[3]); vector<int> cuts; for(int h=0;h<=nmbr_of_threads;h++) { cuts.push_back((int)(size*((double)((double)h/(double)nmbr_of_threads)))); } for(int h=0;h<2*nmbr_of_threads-1;h++) { Search *newSearch = new Search(argv[2]); SearchObjects.push_back(newSearch); } for(int h=1;h<cuts.size()-1;h++) { vector<int> check; Search *newSearch = new Search(argv[2]); newSearch->find(&text[0],cuts[h]-(strlen(argv[2])-1),cuts[h]+(strlen(argv[2])-1)); check = newSearch->get_hits(); if(!check.empty()){ cuts[h]=check[0];} } double start = omp_get_wtime(); #pragma omp parallel num_threads(nmbr_of_threads) shared(SearchObjects,text,cuts) { #pragma omp for schedule(static,1) nowait for(int h=0;h<nmbr_of_threads;h++) { SearchObjects[h]->find(&text[0],cuts[h],cuts[h+1]); } } double end = omp_get_wtime(); vector<int>all_hits; int all_counts = 0; for(int h=0;h<nmbr_of_threads;h++) { vector<int>hits=SearchObjects[h]->get_hits(); for(int hi=0;hi<hits.size();hi++) all_hits.push_back(hits[hi]); all_counts+=SearchObjects[h]->get_count(); } cout<<"\nHorspool:\t"<<all_counts<<" hits found in "<<(int)((end-start)*1000)<<"ms"<<endl; if (!createFile(all_hits, argv[4])) { cerr << "Could not open output file." << endl; return 1; } return 0; }MfG Monchichu
-
Lies dir mal bitte den Link in meiner Signatur durch - vor allem den Teil mit "aufs Wesentliche reduzieren". Zu deinem Problem: sagt der Compiler beim Übersetzen was zum #pragma omp? Musst du ggf. noch irgendeinen Parameter beim compilieren mitgeben? Das ist sehr compilerspezifisch, da OMP kein Standard-C++ ist.
-
Ich kompiliere auf einem Linux mit dem Befehl g++ -Wall -fopenmp xxx.cpp -o xxx und Fehler bekomme ich keine nur unsigned int warnings welche jedoch vernachlässigt werden können.
-
Funktioniert ganz hervorragend bei mir:
[b]$>[/b] g++ test.cc -Wall -Wextra -O3 test.cc: In function ‘bool createFile(std::vector<int, std::allocator<int> >&, char*)’: test.cc:120: warning: comparison between signed and unsigned integer expressions test.cc: In function ‘int main(int, char**)’: test.cc:159: warning: comparison between signed and unsigned integer expressions test.cc:189: warning: comparison between signed and unsigned integer expressions [b]$>[/b] dd if=/dev/urandom of=test.dat bs=10000 count=10000 10000+0 records in 10000+0 records out 100000000 bytes (100 MB) copied, 12.7066 s, 7.9 MB/s [b]$>[/b] ./a.out test.dat test 1 test.result Horspool: 0 hits found in 1273ms [b]$>[/b] ./a.out test.dat test 2 test.result Horspool: 0 hits found in 664ms [b]$>[/b] ./a.out test.dat test 3 test.result Horspool: 0 hits found in 443ms [b]$>[/b] ./a.out test.dat test 4 test.result Horspool: 0 hits found in 332msEinziger Unterschied der mir auffällt zu deinem Versuch ist, dass ich getreu dem Motto "niemanden interessiert es, wie schnell dein unoptimierter Code läuft" gehandelt habe.
-
Das "ganz hervorragend" sollte man noch einschränken: Dein Programm ist ein einziges großes Speicherloch. Warum nutzt du soviel new und Pointergefrickel, wenn du es noch nicht einmal kannst und wenn man es in C++ sowieso nicht braucht und wenn doch, dann ganz anders?