OpenMPを使用してコンピューティングを並列化する

MD5ハッシュからパスワードを回復するというタスクがあります。 パスワードは単純で、7桁で構成され、8桁で始まります。 私はすぐに予約をします-私のパスワード、私はそれを陳腐に忘れました、そしてこれは他人のパスワードを総当たり攻撃する方法についての指示ではありません。



プログラムは、可能な限り迅速に結果を得るために、いくつかのスレッドで動作する必要があります。 デュアルコアプロセッサを搭載したコンピューターで実行するためだけに。 1つのスレッドで両方のコアを最大化することはできません。



2つの方法を検討してください:複数のワークフローを作成する、およびOpenMPを使用する





最初の方法は、複数のスレッドを作成することです。





簡単にするために、結果を出力するときにフローを同期せずに、問題を正面から解決します。 それ以外の場合は、デッドロック、またはむしろそれらの不在に注意する必要があります。

//

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;

}








*このソースコードは、 ソースコードハイライターで強調表示されました。




方法2-OpenMPを使用する





ヘッダーファイルを含める必要があります



#include <omp.h>



/ openmpコンパイラオプションを追加します。 Visual Studioでは、これはプロジェクトプロパティを介して行われます。







//

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;

}








*このソースコードは、 ソースコードハイライターで強調表示されました。




OpenMPを使用すると、コードははるかに短くなります。 この場合、私のコンピューターでの2番目の方法によるパスワードの計算ははるかに高速でした。 両方の方法が両方のコアをほぼ完全に「ロード」したという事実にもかかわらず。



OpenMPに興味がある場合は、IntelのWebサイトに投稿された記事を参照してください。



OpenMPの使用開始

OpenMPを使用したスレッド間の効率的な負荷分散

高度なOpenMPプログラミング



また、 OpenMP Webサイトにアクセスすることを忘れないでください。 そこで、OpenMPおよびOpenMP仕様をサポートするコンパイラのリストを見つけることができます。



All Articles