G
Gwyllum
Суть моей программы - показать, что распараллеливание программы на двухъядерном процессоре способно увеличить скорость вычислений. Программа довольно проста - есть массив из 12 элементов. Программа сперва вычисляет значение каждого. Затем вычисления проводятся с помощью одного процесса. Затем массив разбивается на две части, каждую из которых вычисляют два процесса. Затем на три, на четыре, шесть и двенадцать. Программа замеряет время и строит график.
Как оказалось, время вычисления на двухядернике одним потоком, занимает больше времени, чем обычным кодом. При разбиении на два процесса, это время уменьшается, но при трех - немного увеличивается и т.п. По идее, при вычислении на одноядерном процессоре, разбиение на два потока должно занять больше времени, чем обычное, т.к. тратится дополнительное время на открытие потоков и т.п. Но, результаты приблизительно такие-же.
Подскажите, может в потоках используются какие-то ускоряющие вычисления методы или просто где-то в коде моем ошибка? Пожалуйста, не судите за качество кода - я еще новичок
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
Как оказалось, время вычисления на двухядернике одним потоком, занимает больше времени, чем обычным кодом. При разбиении на два процесса, это время уменьшается, но при трех - немного увеличивается и т.п. По идее, при вычислении на одноядерном процессоре, разбиение на два потока должно занять больше времени, чем обычное, т.к. тратится дополнительное время на открытие потоков и т.п. Но, результаты приблизительно такие-же.
Подскажите, может в потоках используются какие-то ускоряющие вычисления методы или просто где-то в коде моем ошибка? Пожалуйста, не судите за качество кода - я еще новичок
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
C++:
#define ITER 999999
double result[12];
LPVOID atr[2];
DWORD time[7];
DWORD coords[7];
DWORD maxTime;
DWORD WINAPI Calculate(LPVOID value)// function calculate all values
{
int x=11;
int number=(int)atr[1];
for (int j=(int)value*number; j<(int)value*number+number; j++)
{
for (int i=0; i<ITER; i++)
{
result[j]=result[j]+(sqrt(sin((double)x)+cos((double)x ))-sqrt(acos((double)x)+asin((double)x )) );
}
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_CREATE:
{
return 0;
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}break;
case WM_PAINT:
{
InvalidateRect(hwnd, NULL, FALSE);
hdc=BeginPaint(hwnd, &ps);
SelectObject(hdc, penWhite);
SetTextColor(hdc, RGB(255,255,255));
SetBkColor(hdc, RGB(0,0,0));
TextOut(hdc, 20,30,(LPCWSTR)szTitle,6);
MoveToEx(hdc, 50,700, NULL);
LineTo(hdc, 50,50);
MoveToEx(hdc, 50,700, NULL);
LineTo(hdc, 950,700);
for (int i=0; i<7; i++)
{
Ellipse(hdc,i*150+45,693,i*150+45+1 0,703);
}
SelectObject(hdc, penGray);
for (int i=1; i<7; i++)
{
MoveToEx(hdc, i*150+50, 700, NULL);
LineTo(hdc, i*150+50,50);
}
SelectObject(hdc, penGreen);
MoveToEx(hdc, 50, 750-coords[0], NULL);
for (int i=0; i<7; i++)
{
LineTo(hdc, i*150+50,750- coords[i]);
}
EndPaint(hwnd, &ps);
DeleteObject(penWhite);
return 0;
}break;
default: break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpcmdline, int ncmdshow)
{ HANDLE thread0;
HANDLE thread2[2];
HANDLE thread3[3];
HANDLE thread4[4];
HANDLE thread6[6];
HANDLE thread12[12];
DWORD thread_id[27];
for (int i=0; i<12; i++)
{
result[i]=1;
}
int x=11;
DWORD startTime=GetTickCount();//get start time
for (int j=0; j<12; j++)
{
for (int i=0; i<ITER; i++)
{
result[j]=result[j]+(sqrt(sin((double)x)+cos((double)x ))-sqrt(acos((double)x)+asin((double)x )) );
}
}
time[0]=GetTickCount()-startTime;// calculate time running
atr[0]=LPVOID(1);
atr[1]=LPVOID(12);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
thread0=CreateThread(NULL, 0, Calculate, (LPVOID)0, 0, &thread_id[0]);
WaitForSingleObject(thread0, INFINITE);
CloseHandle(thread0);
time[1]=GetTickCount()-startTime;
atr[0]=LPVOID(2);
atr[1]=LPVOID(6);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
for (int i=0; i<(int)atr[0]; i++)
{
thread2[i]=CreateThread(NULL, 0, Calculate, (LPVOID)i, 0, &thread_id[i+1]);
}
WaitForMultipleObjects(2, thread2, TRUE, INFINITE);
for (int i=0; i<(int)atr[0]; i++)
{
CloseHandle(thread2[i]);
}
time[2]=GetTickCount()-startTime;
atr[0]=LPVOID(3);
atr[1]=LPVOID(4);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
for (int i=0; i<(int)atr[0]; i++)
{ thread3[i]=CreateThread(NULL, 0, Calculate, (LPVOID)i, 0, &thread_id[i+3]);
}
WaitForMultipleObjects(3, thread3, TRUE, INFINITE);
for (int i=0; i<(int)atr[0]; i++)
{
CloseHandle(thread3[i]);
}
time[3]=GetTickCount()-startTime;
atr[0]=LPVOID(4);
atr[1]=LPVOID(3);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
for (int i=0; i<(int)atr[0]; i++)
{
thread4[i]=CreateThread(NULL, 0, Calculate, (LPVOID)i, 0, &thread_id[i+6]);
}
WaitForMultipleObjects(4, thread4, TRUE, INFINITE);
for (int i=0; i<(int)atr[0]; i++)
{
CloseHandle(thread4[i]);
}
time[4]=GetTickCount()-startTime;
atr[0]=LPVOID(6);
atr[1]=LPVOID(2);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
for (int i=0; i<(int)atr[0]; i++)
{
thread6[i]=CreateThread(NULL, 0, Calculate, (LPVOID)i, 0, &thread_id[i+10]);
}
WaitForMultipleObjects(6, thread6, TRUE, INFINITE);
for (int i=0; i<(int)atr[0]; i++)
{
CloseHandle(thread6[i]);
}
time[5]=GetTickCount()-startTime;
atr[0]=LPVOID(12);
atr[1]=LPVOID(1);
for (int i=0; i<12; i++)
{
result[i]=1;
}
startTime=GetTickCount();
for (int i=0; i<(int)atr[0]; i++)
{
thread12[i]=CreateThread(NULL, 0, Calculate, (LPVOID)i, 0, &thread_id[i+15]);
}
WaitForMultipleObjects(12, thread12, TRUE, INFINITE);
for (int i=0; i<(int)atr[0]; i++)
{
CloseHandle(thread12[i]);
}
time[6]=GetTickCount()-startTime;
maxTime=0;
for (int i=0; i<7; i++)
{
if (maxTime<time[i])
{
maxTime=time[i];
}
}
for (int i=0; i<7; i++)
{
coords[i]=(time[i]*700)/maxTime;
}
hwnd=CreateWindowEx(NULL, WINDOW_CLASS_NAME, szTitle, WS_VISIBLE|WS_OVERLAPPED, 0,0,1024,768, NULL, NULL, hInstance, NULL);
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}