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;
}