Reputation: 147
I created a merge sort that works fine for arrays of non repeating integers. I am attempting to make a multithreaded version of the same.
I am getting back invalid results.
void mergesort(int data[ ], size_t n)
{
size_t n1; // Size of the first subarray
size_t n2; // Size of the second subarray
if (n > 1)
{
// Compute sizes of the subarrays.
n1 = n / 2;
n2 = n - n1;
mergesort(data, n1); // Sort from data[0] through data[n1-1]
mergesort((data + n1), n2); // Sort from data[n1] to the end
// Merge the two sorted halves.
merge(data, n1, n2);
}
}
DWORD WINAPI threadedmergesort(LPVOID params)
{
size_t n1; // Size of the first subarray
size_t n2; // Size of the second subarray
Params* parameters = (Params*) params;
if (parameters->size > 1)
{
// Compute sizes of the subarrays.
n1 = parameters->size / 2;
n2 = parameters->size - n1;
Params* p1 = new Params(parameters->dataArray, n1);
//mergesort(data, n1); // Sort from data[0] through data[n1-1]
HANDLE h1 = CreateThread(NULL, 0, threadedmergesort, (LPVOID)p1, 0, NULL);
Params* p2 = new Params(parameters->dataArray, n2);
//mergesort((data + n1), n2); // Sort from data[n1] to the end
HANDLE h2 = CreateThread(NULL, 0, threadedmergesort, (LPVOID)p1, 0, NULL);
WaitForSingleObject(h1, INFINITE);
WaitForSingleObject(h2, INFINITE);
// Merge the two sorted halves.
merge(parameters->dataArray, n1, n2);
}
return (DWORD)0x0; //null
}
struct Params
{
int* dataArray;
int size;
Params(int _dataArray[], int _size);
};
Params::Params(int _dataArray[], int _size)
{
dataArray = _dataArray;
size = _size;
}
Could someone comment on why I would get invalid results with the threaded version of the merge sort and what I could do to correct the problem?
Upvotes: 0
Views: 343
Reputation: 5037
A few points to consider:
CreateThread
, use beginThreadEx
instead, see the MSDN for more info.Another alternative to using the thread pool API is to use OpenMP to do a parallel for loop in C++. Visual Studio 2008 and later support that options (and Intel compilers of course).
Upvotes: 0
Reputation: 392
Params* p1 = new Params(parameters->dataArray, n1);
//mergesort(data, n1); // Sort from data[0] through data[n1-1]
HANDLE h1 = CreateThread(NULL, 0, threadedmergesort, (LPVOID)p1, 0, NULL);
Params* p2 = new Params(parameters->dataArray, n2);
//mergesort((data + n1), n2); // Sort from data[n1] to the end
HANDLE h2 = CreateThread(NULL, 0, threadedmergesort, (LPVOID)p1, 0, NULL);
It looks like you're sending p1 twice to the mergesorter. So you're just sorting the first halfs of your list. Change your second parameter and everything should be correct.
My Mergesort looks like this:
DWORD WINAPI Mergesorter::mergesort_MT(LPVOID param)
{
Mergesort_Params* i_mergesortParams = (Mergesort_Params*)param;
unsigned int half = i_mergesortParams->numberOfValues / 2;
DWORD threadId[2] = {0,0};
HANDLE h[2];
Mergesort_Params* mergesortParams;
if(i_mergesortParams->numberOfValues > 1)
{
mergesortParams = new Mergesort_Params[2];
mergesortParams[0].l_list = i_mergesortParams->l_list;
mergesortParams[1].l_list = i_mergesortParams->l_list + half;
mergesortParams[0].numberOfValues = half;
mergesortParams[1].numberOfValues = i_mergesortParams->numberOfValues - half;
h[0] = CreateThread(0,0,mergesort_MT,(void*)&mergesortParams[0],0,&threadId[0]);
//WaitForSingleObject(h[0],INFINITE);
h[1] = CreateThread(0,0,mergesort_MT,(void*)&mergesortParams[1],0,&threadId[1]);
//WaitForSingleObject(h[1],INFINITE);
WaitForMultipleObjects(2,h,TRUE,INFINITE);
merge_ST(i_mergesortParams->l_list,half,i_mergesortParams->numberOfValues - half);
}
//delete threadId;
//delete h;
//delete mergesortParams;
return 0;
}
Did you fix your problem? Now my problem is, that I'm not able to sort enough values 100000 are too much (Single-Threaded no problem) and my CPU isn't used completely (25% on my A8-3500M so just one core)
Upvotes: 1