📜 ⬆️ ⬇️

Using OpenMP to parallelize calculations

There is a task - to recover the password using its MD5 hash. The password is simple, consists of 7 digits and starts with 8-ki. I will make a reservation right away - my password, I forgot it tritely, and this is not an instruction on how to brute force other people's passwords.

The program should work in several threads for the fastest possible results. If only because I will run it on a computer with a dual-core processor. One thread will not be able to maximize both cores.

Consider two ways: creating multiple workflows and using OpenMP
')

Method one is creating multiple threads.



For simplicity, we will solve the problem in the forehead, without synchronizing the threads when displaying the results. Otherwise, you will have to take care of the deadlock, or rather, their absence.
//
const int g_nNumberOfThreads = 4;

const int g_nFrom = 8000000;
const int g_nTo = 8999999;
const string g_strCompareWith = "4ac7b1796b90478f2991bb9a7b05d2bf" ;

time_t g_timeElapsed;

// ,
struct THREAD_PARAMS
{
int nFrom;
int nTo;
};

// MD5
BOOL GetMD5Hash( string strIn, string &strHash)

//
DWORD WINAPI _WorkerThread(LPVOID pParams)
{
//
THREAD_PARAMS *pThreadParams = (THREAD_PARAMS*)pParams;

int nFrom = pThreadParams->nFrom;
int nTo = pThreadParams->nTo;

delete pParams;

string strHash;

for ( int i = nFrom; i < nTo; ++i)
{
stringstream stream;
stream << i;

//
GetMD5Hash(stream.str(), strHash);

//
if (strHash == g_strCompareWith)
{
//
cout << "Password is: " << stream.str() << endl;
cout << "Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
exit(0);
}

// 10000
if ((i % 10000) == 0)
{
cout << "Current password: " << i << " Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
}
}

return 0;
}

//
void MultiThreadWay()
{
int nDataLength = ( int )(g_nTo - g_nFrom) / g_nNumberOfThreads;
HANDLE *hThreads = new HANDLE[g_nNumberOfThreads];

for ( int i = 0; i < g_nNumberOfThreads; ++i)
{
THREAD_PARAMS *pParams = new THREAD_PARAMS();

pParams->nFrom = g_nFrom + (i * nDataLength);
pParams->nTo = pParams->nFrom + nDataLength;

hThreads[i] = CreateThread(NULL, 0, _WorkerThread, pParams, 0, NULL);

Sleep(100);
}

WaitForMultipleObjects(g_nNumberOfThreads, hThreads, TRUE, INFINITE);

delete [] hThreads;
}

//
int _tmain( int argc, _TCHAR* argv[])
{
g_timeElapsed = time(NULL);

MultiThreadWay();

return 0;
}


* This source code was highlighted with Source Code Highlighter .


Method two - using OpenMP



You must include a header file.

#include <omp.h>

And add the / openmp compiler option. In Visual Studio, this is done through project properties.



//
const int g_nNumberOfThreads = 4;

const int g_nFrom = 8000000;
const int g_nTo = 8999999;
const string g_strCompareWith = "4ac7b1796b90478f2991bb9a7b05d2bf" ;

time_t g_timeElapsed;

// MD5
BOOL GetMD5Hash( string strIn, string &strHash)

int _tmain( int argc, _TCHAR* argv[])
{
g_timeElapsed = time(NULL);

//
omp_set_num_threads(g_nNumberOfThreads);

// , .
// g_nNumberOfThreads .
// .
#pragma omp parallel for
for ( int i = g_nFrom; i < g_nTo; ++i)
{
//
//
string strHash;
stringstream stream;

stream << i;

//
GetMD5Hash(stream.str(), strHash);

//
if (strHash == g_strCompareWith)
{
cout << "Password is: " << stream.str() << endl;
cout << "Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
exit(0);
}

// 10000
if ((i % 10000) == 0)
{
// .
// , ""
#pragma omp critical
{
cout << "Current password: " << i << " Elapsed time: " << time(NULL) - g_timeElapsed << " sec." << endl;
}
}
}

return 0;
}


* This source code was highlighted with Source Code Highlighter .


Using OpenMP, the code is much shorter. In this case, the second method of calculating the password, on my computer, was performed much faster. Despite the fact that both methods "loaded" both cores almost completely.

If you are interested in OpenMP, you can start exploring with articles posted on the Intel website.

Getting started with OpenMP
Efficient load balancing between threads using OpenMP
Advanced openmp programming

And do not forget to visit the site OpenMP . There you can find a list of compilers that support OpenMP and OpenMP specifications.

Source: https://habr.com/ru/post/71296/


All Articles