Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> многопоточное вычисление 
:(
    Опции темы
denisminb
Дата 13.5.2013, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Добрый день,подскажите пожалуйста в вопросе многопоточности, читаю книги, смотрю разные реализации, в общем начал практиковаться,не совсем получается мне кажется.
Для примера,может конечно не совсем удачно, взял вычисление числа PI c определенной точностью.
без использования потоков, было нечто такое:
описан прототип фукнции
сама функция
в мейне вызов функции, вывод результата итд
использую 
Код

#include <pthread.h>

для того чтобы работало с потоками добавил в функцию void*
Код

void *pi_calc(void*);

Код

int main()
{
    int id, result;
    pthread_t    our_thread_id;
    id = 1;
    ..........
              ...........
    if (Variant == 2) //Если вычисляем по заданной точности

     result = pthread_create(&our_thread_id,NULL,&pi_calc,&id);
     if (result != 0) {
                perror("Creating the first thread");
              return EXIT_FAILURE;
               }
           pthread_join(our_thread_id, NULL);
           pause();

          /*Код для варианта без использования потоков,вывода результата работы функции
            double* q; // Создали указатель для приема результата
            q=(double*)pi_calc(); // Приняли результат, преобразовав нужным образом тип возвращаемого указателя
           cout<<"Результат : "<<setprecision(20)<< *q << endl;
           free(q);
         */
     return EXIT_SUCCESS;
}


примерно так
так вот, прога компилится, вроде как поток создается,но результат вычисления функции не отображается,не могу понять,что ещё нужно сделать
хочу получить в итоге, распараллеливание вычислений, с использованием нескольких потоков итд

PM MAIL   Вверх
Фантом
Дата 13.5.2013, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 1
Всего: 49



Пока что в этом коде результат вычисления функции отображать просто нечему (то, что закомментировано, не в счет).
PM   Вверх
denisminb
Дата 13.5.2013, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(Фантом @ 13.5.2013,  19:08)
Пока что в этом коде результат вычисления функции отображать просто нечему (то, что закомментировано, не в счет).

Код

void *pi_calc(void*arg)
{
    int loc_id = * (int *) arg;
    clock_t startclock = clock();
    double Esp; //Точность вычисления (вариант 2)
    unsigned long delit = 1; //Делитель члена ряда
    cout << "Введите заданную точность вычисления (0.00000001) : ";
    cin >> Esp; //Введем точность
    double* PI;
    PI=(double*)malloc(sizeof(double));
    int i=0;
    double Ryad = 4; //Текуйщи член ряд
    while (Ryad > Esp) //Пока текущий член ряда > нашей заданной точности
    {
                Ryad = (double)4/delit; //Вычислим член ряда
                if (i %2 == 0)
                    *PI+= Ryad;
                else
                 *PI-= Ryad;
                delit+=2;
                i++;
    }

    printf ("Результат: %9.3f",PI);
    return PI;
}


сама функция
PM MAIL   Вверх
Фантом
Дата 13.5.2013, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 1
Всего: 49



Она у Вас просто зацикливается, причем потоки тут совершенно не при чем.

P.S. Кстати, Вы действительно хотите делать ввод параметров в каждом потоке?
PM   Вверх
denisminb
Дата 13.5.2013, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(Фантом @ 13.5.2013,  20:22)
Она у Вас просто зацикливается, причем потоки тут совершенно не при чем.

P.S. Кстати, Вы действительно хотите делать ввод параметров в каждом потоке?

while (Ryad > Esp) - ну да, здесь зацикливание,


скорей всего нет, правильней будет один раз ввести данные,правильно же?
PM MAIL   Вверх
Фантом
Дата 13.5.2013, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 1
Всего: 49



Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

while (Ryad > Esp) - ну да, здесь зацикливание,

Именно.

Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

скорей всего нет, правильней будет один раз ввести данные,правильно же? 

Конечно. Это и со смысловой, и с технической точки зрения разумнее.
PM   Вверх
denisminb
Дата 13.5.2013, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(Фантом @ 13.5.2013,  21:00)
Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

while (Ryad > Esp) - ну да, здесь зацикливание,

Именно.

Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

скорей всего нет, правильней будет один раз ввести данные,правильно же? 

Конечно. Это и со смысловой, и с технической точки зрения разумнее.

самое интересное,то что функция возвращала правильное значение Pi, без использования потоков
PM MAIL   Вверх
denisminb
Дата 14.5.2013, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(Фантом @ 13.5.2013,  21:00)
Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

while (Ryad > Esp) - ну да, здесь зацикливание,

Именно.

Цитата(denisminb @  13.5.2013,  21:54 Найти цитируемый пост)

скорей всего нет, правильней будет один раз ввести данные,правильно же? 

Конечно. Это и со смысловой, и с технической точки зрения разумнее.

можно ещё вопрос?
как думаете лучше вообще переписать алгоритм без использования While?
или например от того чтобы не зацикливало,добавил
Код

                            double Ryad = 1; //Текуйщи член ряд
        while (fabs(Ryad) > Esp && i<100000) //Пока текущий член ряда > нашей заданной точности и кол-во членов ряда <100000
        {
                    Ryad = (double)4/delit; //Вычислим член ряда
                    delit+=2;
                    if (i %2 == 0)
                        PI+= Ryad;
                    else
                        PI-= Ryad;

                    i++;
        }

        cout<<"Результат : "<<setprecision(20)<< PI<< endl;


PM MAIL   Вверх
Фантом
Дата 14.5.2013, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 1
Всего: 49



Цитата(denisminb @  14.5.2013,  22:41 Найти цитируемый пост)

как думаете лучше вообще переписать алгоритм без использования While?

Хм... в каком смысле "лучше"?
PM   Вверх
rsm
Дата 15.5.2013, 02:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(denisminb @  13.5.2013,  20:55 Найти цитируемый пост)
Для примера,может конечно не совсем удачно, взял вычисление числа PI c определенной точностью

Для сугубо численных вычислений лучше использовать OpenMP.

Цитата(denisminb @  14.5.2013,  23:41 Найти цитируемый пост)
как думаете лучше вообще переписать алгоритм без использования While?

Цикл нужен так или иначе, просто каждому потоку нужно выделить определённый интервал вычислений количества знаков после запятой, как-то так:
[0, 10000) - первый поток;
[10000, 20000) - второй;
[20000, 30000) - третий;
[20000, 40000) - четвёртый;
и т.д. в том же духе. Оптимальное количество потоков обычно принимают равным количеству ядер процессора * 2 + 1.
PM MAIL   Вверх
denisminb
Дата 15.5.2013, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(Фантом @ 14.5.2013,  23:53)
Цитата(denisminb @  14.5.2013,  22:41 Найти цитируемый пост)

как думаете лучше вообще переписать алгоритм без использования While?

Хм... в каком смысле "лучше"?

я просто имел ввиду,как лучше сделать?
PM MAIL   Вверх
denisminb
Дата 15.5.2013, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(rsm @ 15.5.2013,  02:57)
Цитата(denisminb @  13.5.2013,  20:55 Найти цитируемый пост)
Для примера,может конечно не совсем удачно, взял вычисление числа PI c определенной точностью

Для сугубо численных вычислений лучше использовать OpenMP.

Цитата(denisminb @  14.5.2013,  23:41 Найти цитируемый пост)
как думаете лучше вообще переписать алгоритм без использования While?

Цикл нужен так или иначе, просто каждому потоку нужно выделить определённый интервал вычислений количества знаков после запятой, как-то так:
[0, 10000) - первый поток;
[10000, 20000) - второй;
[20000, 30000) - третий;
[20000, 40000) - четвёртый;
и т.д. в том же духе. Оптимальное количество потоков обычно принимают равным количеству ядер процессора * 2 + 1.

в принципе в теории я понимаю что для того чтобы программа была многопоточная,вычисляла параллельно,нужно распараллелить алгоритм,разбить на блоки.
только не пойму как в моём варианте сделать?
На данном этапе, в цикле вычисляю очередной член ряда и затем суммирую,выхожу из цикла по количеству итераций.
Вы пишите, что нужно разбить на интервалы,этот контекст не совсем понимаю.
я думал если разбить по количеству итераций, но как собрать результаты потоков?тогда нужно для каждого интервала писать свою функцию вызова для pthread_create?


P.S. Нужно сделать без OpenMP, точнее даже нужно два варианта без него и с ним. Но пока его не нужно.
 

PM MAIL   Вверх
rsm
Дата 15.5.2013, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(denisminb @  15.5.2013,  20:40 Найти цитируемый пост)
только не пойму как в моём варианте сделать?

Приведённую выше статью всё-таки стоит почитать smile
PM MAIL   Вверх
denisminb
Дата 15.5.2013, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(rsm @ 15.5.2013,  20:01)
Цитата(denisminb @  15.5.2013,  20:40 Найти цитируемый пост)
только не пойму как в моём варианте сделать?

Приведённую выше статью всё-таки стоит почитать smile

спасибо за статью,ознакомлюсь, сделал так, с блокировками
Код

#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <sys/neutrino.h>
#include <pthread.h>
#include <errno.h>
#include <sched.h>
#include <unistd.h>
#include <math.h>

#define INTERVALS 100000
#define THREADS 4


using namespace std;

float global_sum = 0.0;
pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;

void *pi_calc(void *);

int main ()
{
  pthread_t tid[THREADS];
  int i,result;
  int t_num[THREADS];

  for (i = 0; i < THREADS; i++)
  {
    t_num[i] = i;
    result = pthread_create(&tid[i], NULL, pi_calc, &t_num[i]);
    if (result != 0) {
     perror("Creating the thread");
     return EXIT_FAILURE;
    }
  }

  for (i = 0; i < THREADS; i++){
      result = pthread_join (tid[i], NULL);
      if (result != 0) {
                perror("Joining the first thread");
                return EXIT_FAILURE;
              }
  }
  cout<<"Результат : "<<setprecision(20)<< global_sum<< endl;
}

void *pi_calc(void *)
{
  double my_pi = 0.0;
  double h = 1.0 / INTERVALS;
  double x;
  int i;
  for (i = 1; i < INTERVALS; i++)
  {
    x = ((double)i - 0.5)*h;
    my_pi = my_pi+ 4.0 / (1.0 + x * x);
  }

  pthread_mutex_lock(&global_lock);
  global_sum = my_pi*h;
  pthread_mutex_unlock(&global_lock);
}



Добавлено через 6 минут и 21 секунду
ага,только не совсем понимаю,как запустить в qnx версию с openMP, как хидер подключить?

Это сообщение отредактировал(а) denisminb - 15.5.2013, 20:27
PM MAIL   Вверх
Фантом
Дата 16.5.2013, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 1
Всего: 49



Цитата(denisminb @  15.5.2013,  19:22 Найти цитируемый пост)

я просто имел ввиду,как лучше сделать? 

Задача слишком "ненастоящая", чтобы можно было просто так выбирать что-то лучшее. Например, с математической точки зрения лучше воспользоваться оценкой остатка для ряда и, зная необходимую точность, заранее вычислить необходимое число членов (и тогда цикл while, понятно, не нужен).
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1393 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.