I was reading up on multithreading and I came across things like Mutexes, Locks, Starvation and it's quite interesting. Here I'm using CRITICAL_SECTION in my code to prevent data corruption and so forth. I could have used Mutexex, Events, Semaphores, etc... I managed to read and add the contents of a 5MB text file in about 5.9 seconds with 7 threads. This is a big improvement since I had a program before that took a whole 10 seconds to read and add the contents of a 1MB file to a vector. This one uses maps and counts each word's/phrase occurrences. The speed is highly dependent on the placement of the critical sections. I shaved off about 4 seconds just by moving the EnterCriticalSection down one line!!
I'm looking for other ways to optimize the CRITICAL_SECTIONS though. I want to get this down to at least 3 seconds if possible. xD
Code:#include <windows.h> #include <process.h> #include <iostream> #include <string> #include <fstream> #include <map> #include <time.h> using namespace std; map <string, long> words; ifstream f; CRITICAL_SECTION c, c2; unsigned int __stdcall thread(void *) { string buffer; map <string, long>::iterator iter; while (f >> buffer) { EnterCriticalSection(&c); f >> buffer; LeaveCriticalSection(&c); iter = words.find(buffer); EnterCriticalSection(&c2); if (iter != words.end()) iter->second++; else words.insert(make_pair(buffer, 1)); LeaveCriticalSection(&c2); } return 0; } int main() { cout << "How much threads do you want to use? -> "; int thread_count; cin >> thread_count; f.open("file.txt", ios::in); clock_t t1, t2; if (f.is_open()) { InitializeCriticalSection(&c); InitializeCriticalSection(&c2); t1 = clock(); HANDLE * hThreads = (HANDLE *)malloc(sizeof(HANDLE) * thread_count); for(int i = 0; i < thread_count; i++) hThreads[i] = (HANDLE) _beginthreadex(0, 0, &thread, (void *)0, 0, 0); WaitForMultipleObjects(thread_count, hThreads, true, INFINITE); t2 = clock(); for(int i = 0; i < thread_count; i++) CloseHandle(hThreads[i]); DeleteCriticalSection(&c2); DeleteCriticalSection(&c); f.close(); map<string, long>::iterator iter = words.begin(); //IF YOU WISH TO DISPLAY THE MAP /*for(; iter != words.end(); iter++) cout << iter->first.c_str() << " - " << iter->second << endl;*/ cout << "Unique WOrD CoUNt -> " << words.size() << endl; } else { cout << "The file couldn't be opened" << endl; } cout << "Word count took " << (double(t2 - t1) / 1000) << " second(s) with " << thread_count << " threads"; words.clear(); std::cin.ignore(); std::cin.get(); return 0; }



LinkBack URL
About LinkBacks


