Модераторы: 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   Вверх
Google
  Дата 25.6.2019, 00:39 (ссылка)  





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

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

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


 




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


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

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