Многопоточное вычисление числа пи в WinAPI
Есть учебное задание: напишите параллельную программу, вычисляющую число пи с точностью N знаков после запятой по следующей формуле:
, где
Установите n=1000000000. Создание потоков выполняйте с помощью функции CreateThread. Рекомендуется сразу в начале программы сразу создать необходимое количество потоков в приостановленном состоянии.
Произведите замер времени выполнения вашей программы. Проведите эксперименты для определения количества потоков в программе (от одного до 16), при котором достигается наибольшая скорость выполнения.
Используемые функции Win32 API: CreateThread, ResumeThread, SuspendThread"
Реализуемые способы:
1)Статическое распределение итераций блоками (размер блока 100) по потокам.
Первый блок из 100 итераций выполняет нулевой поток, второй блок – следующий и т.д. до последнего потока, затем распределение снова начинается с нулевого потока.
2) Статическое распределение итераций блоками (размер блока 100) по потокам.
Сначала каждый поток 100 итераций, тот поток, который заканчивает выполнение своей порции итераций, получает следующую свободную порцию из 100 итераций. Освободившиеся потоки получают новые порции итераций до тех пор, пока все порции не будут исчерпаны.
Вот, что есть для 1 способа, но я НЕ ЗНАЮ как это переделать во 2 способ, очень прошу помощи!
Код:
// L60.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <conio.h>
#include <time.h>
#include <iostream>
#include <locale>
using namespace std;
#define MAX_THREADS 10
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
typedef struct NumberOfPi {
int i,number,j;
double pi;
}NuOPi,*PNuOPi;
void main( void)
{
setlocale(LC_ALL,"Russian");
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
PNuOPi pDataArray[MAX_THREADS];
double pi=0, N=1000000000,time[MAX_THREADS];
unsigned long t1=0,t2=0;
int i,j=MAX_THREADS;
cout<<"Ждите..."<<endl;
for(i=0;i<j;i++)
{
pDataArray[i] = (PNuOPi) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(NuOPi));
pDataArray[i]->i = i*100;
pDataArray[i]->pi = 0;
pDataArray[i]->number=i;
pDataArray[i]->j=j;
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pDataArray[i], // argument to thread function
CREATE_SUSPENDED,
&dwThreadIdArray[i]); // returns the thread identifier
}
t1=clock();
for( int i=0; i<j; i++ )
ResumeThread(hThreadArray[i]);
WaitForMultipleObjects(j, hThreadArray, TRUE, INFINITE);
t2=clock();
time[j-1]=t2-t1;
for(int i=0; i<j; i++)
{
pi=pi+pDataArray[i]->pi;
CloseHandle(hThreadArray[i]);
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
}
printf("\npi: %lf",pi/N);
wcout<<L" \nВремя "<<(time[j-1])/(double)CLOCKS_PER_SEC <<endl;
getch();
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
HANDLE hStdout;
PNuOPi pDataArray;
pDataArray = (PNuOPi)lpParam;
double pi=0, x;
double N=1000000000;
while(pDataArray->i<N)
{
for(int j=0;j<100 && j+pDataArray->i<N;j++)
{
x=(j+pDataArray->i+0.5)*1/N;
pi=pi+4/(1+x*x);
}
pDataArray->i=pDataArray->i+pDataArray->j*100;
}
pDataArray->pi=pDataArray->pi+pi;
return 0;
}
//
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <conio.h>
#include <time.h>
#include <iostream>
#include <locale>
using namespace std;
#define MAX_THREADS 10
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
typedef struct NumberOfPi {
int i,number,j;
double pi;
}NuOPi,*PNuOPi;
void main( void)
{
setlocale(LC_ALL,"Russian");
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
PNuOPi pDataArray[MAX_THREADS];
double pi=0, N=1000000000,time[MAX_THREADS];
unsigned long t1=0,t2=0;
int i,j=MAX_THREADS;
cout<<"Ждите..."<<endl;
for(i=0;i<j;i++)
{
pDataArray[i] = (PNuOPi) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(NuOPi));
pDataArray[i]->i = i*100;
pDataArray[i]->pi = 0;
pDataArray[i]->number=i;
pDataArray[i]->j=j;
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
pDataArray[i], // argument to thread function
CREATE_SUSPENDED,
&dwThreadIdArray[i]); // returns the thread identifier
}
t1=clock();
for( int i=0; i<j; i++ )
ResumeThread(hThreadArray[i]);
WaitForMultipleObjects(j, hThreadArray, TRUE, INFINITE);
t2=clock();
time[j-1]=t2-t1;
for(int i=0; i<j; i++)
{
pi=pi+pDataArray[i]->pi;
CloseHandle(hThreadArray[i]);
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
}
printf("\npi: %lf",pi/N);
wcout<<L" \nВремя "<<(time[j-1])/(double)CLOCKS_PER_SEC <<endl;
getch();
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
HANDLE hStdout;
PNuOPi pDataArray;
pDataArray = (PNuOPi)lpParam;
double pi=0, x;
double N=1000000000;
while(pDataArray->i<N)
{
for(int j=0;j<100 && j+pDataArray->i<N;j++)
{
x=(j+pDataArray->i+0.5)*1/N;
pi=pi+4/(1+x*x);
}
pDataArray->i=pDataArray->i+pDataArray->j*100;
}
pDataArray->pi=pDataArray->pi+pi;
return 0;
}