Многопоточное вычисление числа пи
От: zombiecomatozzz  
Дата: 11.12.10 13:20
Оценка: :))) :))) :))) :))) :))
требуется написать программу для многопоточного вычисления числа пи по формуле pi/4=1-1/3+1/5-1/7+... Попробовал вот так:

#include "stdafx.h"
#include "iostream."
#include "windows.h"
using namespace std;

const DWORD NUM_THREAD = 8;
int n=0;
double pi=0;
HANDLE hMutex;
int k=-1;
DWORD WINAPI ThreadProc()
{
    while(n<1000000)
    {
        WaitForSingleObject(hMutex, INFINITE);
        k*=-1;
        pi+=k*4./(2*n+1);
        n++;
        ReleaseMutex(hMutex);
    }
    return 1;
}

int main()
{
    hMutex = CreateMutex( NULL, FALSE, NULL );
    for(int i=0; i<NUM_THREAD; i++)                    
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadProc,0,0,0);   
    cout<<pi;
    cin.get();
}


получаются всегда разные значения и не слишком точные. например 3.13413 Подскажите что не так делаю?
Re: Многопоточное вычисление числа пи
От: remark Россия http://www.1024cores.net/
Дата: 11.12.10 13:30
Оценка:
Здравствуйте, zombiecomatozzz, Вы писали:

Z>требуется написать программу для многопоточного вычисления числа пи по формуле pi/4=1-1/3+1/5-1/7+... Попробовал вот так:

Z>получаются всегда разные значения и не слишком точные. например 3.13413 Подскажите что не так делаю?

Завершения потоков надо ждать, иначе ты выводишь число пока потоки его ещё считают.
Числа с плаваещей точкой надо суммировать надо начиная с меньших по абсолютному значению чисел, иначе будет большая погрешность.
Каждый поток должен накапливать свою частную сумму, по завершению потоков их надо сложить, иначе синхронизация убьёт любое ускорение от многопоточности.
Слагаемые надо распределять между потоками либо статически алгоритмически (например, первый поток суммирует от 0 до 999, второ от 1000 до 999 и т.д.), либо динамически, но большими пачками. Иначе синхронизация иначе синхронизация убьёт любое ускорение от многопоточности.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Многопоточное вычисление числа пи
От: uzhas Ниоткуда  
Дата: 11.12.10 13:34
Оценка:
Здравствуйте, zombiecomatozzz, Вы писали:

Z>требуется написать программу для многопоточного вычисления числа пи по формуле pi/4=1-1/3+1/5-1/7+... Попробовал вот так:

программа, конечно, многопоточная, но, думаю, что требуется подойти к решению с другой стороны
у вас вся многопоточность убита мьютексом, то есть параллельного выполнения нет и по перформансу то же самое, что запустить в одном потоке
попробуйте так:
задали N — кол-во слагаемых из ряда
задали k — кол-во потоков
далее каждому потоку даем свою подзадачу : например, потоку номер z подсчитать сумму элементов ряда с индексами z, z + k, z + 2*k, z + 3*k, ..., которые меньше N
после того, как все потоки отработали, надо собрать воедино k чисел (одно число из потока) и сложить их в main, это и будет результат выполнения всех потоков

Z>int main()

Z>{
Z> hMutex = CreateMutex( NULL, FALSE, NULL );
Z> for(int i=0; i<NUM_THREAD; i++)
Z> CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadProc,0,0,0);
//here we need to wait for all threads, use returned handle from CreateThread
Z> cout<<pi;
Z> cin.get();
Z>}

Z>[/ccode]


Z>получаются всегда разные значения и не слишком точные. например 3.13413 Подскажите что не так делаю?

в коде написал комментарий : вы выводите результат, хотя вычисления еще не закончились во всех потоках
успехов
Re: Многопоточное вычисление числа пи
От: Sni4ok  
Дата: 11.12.10 13:38
Оценка: +1
Здравствуйте, zombiecomatozzz, Вы писали:

Z>требуется написать программу для многопоточного вычисления числа пи по формуле pi/4=1-1/3+1/5-1/7+... Попробовал вот так:


и в чём же ваше проявление многопоточности? если всё вычесление выполняется под одним мутексом, а вообще за такой код 2ку при обучении нужно ставить, или с работы увольнять по проф. непригодности.
Re[2]: Многопоточное вычисление числа пи
От: Libsdebs  
Дата: 11.12.10 13:40
Оценка: 9 (2)
Здравствуйте, remark, Вы писали:

R>Числа с плаваещей точкой надо суммировать надо начиная с меньших по абсолютному значению чисел, иначе будет большая погрешность.


Не всегда практично складывать начиная именно с меньших, как компромисс между скоростью и точностью можно применять http://en.wikipedia.org/wiki/Kahan_summation_algorithm — советую хотя бы одним глазком взглянуть для общего развития.
Re[2]: Многопоточное вычисление числа пи
От: Libsdebs  
Дата: 11.12.10 13:44
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>и в чём же ваше проявление многопоточности? если всё вычесление выполняется под одним мутексом, а вообще за такой код 2ку при обучении нужно ставить, или с работы увольнять по проф. непригодности.


Прям как тут —
http://www.rsdn.ru/forum/abroad/4064738.aspx
Автор: мыщъх
Дата: 04.12.10
— ему сказали многопоточное сделать, он и сделал..
Re[3]: Многопоточное вычисление числа пи
От: dilmah США  
Дата: 11.12.10 13:49
Оценка:
L>Не всегда практично складывать начиная именно с меньших

в данном конкретном случае это не составляет никакого труда.
Re[2]: Многопоточное вычисление числа пи
От: zombiecomatozzz  
Дата: 11.12.10 13:50
Оценка:
Здравствуйте, remark, Вы писали:


R>Каждый поток должен накапливать свою частную сумму, по завершению потоков их надо сложить, иначе синхронизация убьёт любое ускорение от многопоточности.

То есть для каждого потока надо свою функцию писать?
Re[4]: Многопоточное вычисление числа пи
От: Libsdebs  
Дата: 11.12.10 13:52
Оценка:
Здравствуйте, dilmah, Вы писали:

L>>Не всегда практично складывать начиная именно с меньших

D>в данном конкретном случае это не составляет никакого труда.

Да, согласен, я это тоже увидел, я в общем имел ввиду.
Re[3]: Многопоточное вычисление числа пи
От: Wissenschaftler http://rsdn_user.livejournal.com
Дата: 11.12.10 13:58
Оценка:
Здравствуйте, zombiecomatozzz, Вы писали:

Z>Здравствуйте, remark, Вы писали:



R>>Каждый поток должен накапливать свою частную сумму, по завершению потоков их надо сложить, иначе синхронизация убьёт любое ускорение от многопоточности.

Z>То есть для каждого потока надо свою функцию писать?
Кури параметры у ThreadProc
Запретное обсуждение модерирования RSDN:
http://rsdn-user.livejournal.com/652.html
Re: Многопоточное вычисление числа пи
От: uzhas Ниоткуда  
Дата: 11.12.10 14:05
Оценка:
Здравствуйте, zombiecomatozzz, Вы писали:

Z>DWORD WINAPI ThreadProc()


вот здесь ошибочка
сигнатура должна быть другой, чтобы эту функцию можно было запускать в отдельном потоке
http://msdn.microsoft.com/en-us/library/ms686736(v=vs.85).aspx


>> То есть для каждого потока надо свою функцию писать?


вам нужно написать одну функцию, принимающую параметр
и запустить ее в разных потоках с разными параметрами
обычно это проворачивают так:
struct Task
{
  //some data
};

DWORD WINAPI MyThreadFunc(void* data)
{
  Task task = *static_cast<Task*>(data);
  //work on task
}

int main()
{
  Task newTask = ...
  HANDLE threadHandle = CreateThread(0, 0, &MyThreadFunct, &newTask, 0, 0);
  WaitForSingleObject(threadHandle, INFINITE);
}
Учись, студент
От: rm822 Россия  
Дата: 11.12.10 14:54
Оценка: +1 :)
#include <omp.h>

int _tmain(int argc, _TCHAR* argv[])
{
    const int steps = 1000000000;
    double res = 0 ;
    #pragma omp parallel for reduction(+ : res) schedule(static, 100000)
    for(int i=0; i< steps; ++i)
    {
        int k = steps-i-1;
        res += 1.0/(1+4*k) - 1.0/(1+4*k+2);
    }
    printf("%1.10f\n", res*4);
    return 0;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.