Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/32: Рейтинг темы: голосов - 32, средняя оценка - 4.72
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972

распараллеливание

13.05.2013, 18:04. Показов 6400. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Скажите, кто-нибудь занимался распараллеливанием в си++? В моих попытках что-либо распараллелить через omp все выходило только в несколько раз медленнее. По сути у меня 8 ядер на ноуте, но их задействовать что-то не получается. По большей степени мне надо распараллеливать циклы. Если кто-то баловался этим, то помогите мне рабочим примером.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.05.2013, 18:04
Ответы с готовыми решениями:

Распараллеливание
Всем добрый вечер. Если кто знает подскажите,мне надо распараллелить перемножение матриц,преподаватель сказал,что это делается просто с...

Распараллеливание
Подскажите, что не так. Есть массив из 13 элементов, мне нужно разбить на три блока, один блок может быть неполный. При этом чтоб была...

Распараллеливание циклов
Возникли трудности с освоением OpenMP Непонимаю, почему если закоментировать вот этот фрагмент кода, то программа работает вы разы...

16
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
13.05.2013, 18:21
тебе нужна многопоточность, вообще многопроцессорность, но почитай про многопоточность))
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.05.2013, 18:34
Можете описать на конкретных примерах, что именно не получается ?
0
 Аватар для Ternsip
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
13.05.2013, 18:39
mat_for_c, Мне 1 раз надо было сделать прекальк расстановки магарадж, так вот я врубил 8 процессов независимых и даже не парился с openmp, кстати в omp нужно очень аккуратно.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
13.05.2013, 19:00  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Можете описать на конкретных примерах, что именно не получается ?
Например, мне можно распараллелить следующий цикл:
C++
1
2
3
4
5
6
7
8
9
10
11
#pragma omp parallel for
    for (i = 0; i < col_count - 1; ++i) {
        Mw[i].resize(indexW_size);
        Mnw[i].resize(indexnW_size);
        for (j = 0; j < maximum_index; ++j) {
            if (j < indexW_size)
                Mw[i][j] = Data[indexW[j]][i];
            if (j < indexnW_size)
                Mnw[i][j] = Data[indexnW[j]][i];
        }
    }
с использованием #pragma omp parallel for работает 3 миллисекунды, а без - 0. Но это пока массив данных маленький...

и еще вопрос. Если в цикле используется контейнер vector<> и его метод push_back(), то можно ли распараллелить такой цикл?
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
13.05.2013, 19:24
Цитата Сообщение от mat_for_c Посмотреть сообщение
с использованием #pragma omp parallel for работает 3 миллисекунды, а без - 0.
Объемы вычислений смешные. Классический пример - напишите перемножение матриц большого размера, проведите замеры.

Добавлено через 2 минуты
Цитата Сообщение от mat_for_c Посмотреть сообщение
и еще вопрос. Если в цикле используется контейнер vector<> и его метод push_back(), то можно ли распараллелить такой цикл?
Этот метод не является потокобезопасным.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
13.05.2013, 20:00  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
Объемы вычислений смешные. Классический пример - напишите перемножение матриц большого размера, проведите замеры.
Сделал ... Вот результаты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <ctime>
#include <omp.h>
 
using namespace std;
 
int main(void)
{
    srand(time(NULL));
    short a[2000][100], b[100][3000];//, p[2000][3000]; --- места на него не хватило :)
    int i, j, k, sum;
    for (i = 0; i < 2000; ++i)
        for (j = 0; j < 100; ++j) {
            a[i][j] = rand()%10;
        }
    for (i = 0; i < 100; ++i)
        for (j = 0; j < 3000; ++j) {
            b[i][j] = rand()%10;
        }
    
    //без  -- 2096 мс
    clock_t beg = clock();
//#pragma omp parallel for -- 9297 мс
    for (i = 0; i < 2000; ++i) {
    //#pragma omp parallel for  //-- 5439 мс
        for (j = 0; j < 3000; ++j) {
            sum = 0;
            //#pragma omp parallel for // оооочень долго
            for (k = 0 ; k < 100; ++k)
                sum += a[i][k]*b[k][j];
            //p[i][j] = sum; - т.к. массива нет
        }
    }
    clock_t end = clock();
    cout << end - beg << endl;
    system("pause");
    return 0;
}
время указано там, где использовался omp для конкретного цикла. почему такие результаты большие???
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
13.05.2013, 20:29
Цитата Сообщение от mat_for_c Посмотреть сообщение
p[2000][3000]; --- места на него не хватило
Ну сделайте ж динамическое выделение памяти.

Функция clock ситает процессорное время. Воспользуйтесь какой-нибудь gettimeofday.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
14.05.2013, 11:30  [ТС]
Цитата Сообщение от 0x10 Посмотреть сообщение
Ну сделайте ж динамическое выделение памяти.
Это не особо важно. Основной смысл перемножения расписан.


Цитата Сообщение от 0x10 Посмотреть сообщение
Функция clock ситает процессорное время. Воспользуйтесь какой-нибудь gettimeofday.
как я понял, gettimeofday в линуксе работает, в то время как у меня винда стоит, да и в статье про нее писали, что все же лучше получить процессорное время...
http://ccfit.nsu.ru/~kireev/lab1/lab1time.htm
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
14.05.2013, 12:00
Время можно замерить при помощи самого OpenMP.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <omp.h>
#include <cstdio>
#include <cmath>
 
int main()
{
    double  start;
    double  result[8];
 
    start = omp_get_wtime();
 
    #pragma omp parallel for
    for ( int i = 0; i < 8; i++ ) {
        result[i] = 0;
        for ( int j = 0; j < 1000000; j++ ) {
            result[i] += (pow( i + 1, 1.1 )) * sqrt( i * j );
        }
    }
 
    printf( "Elapsed = %.2f\n", omp_get_wtime() - start );
 
    for ( int i = 0; i < 8; i++ ) {
        printf( "%2d: %.4f\n", i, result[i] );
    }
 
    return 0;
}
2
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
14.05.2013, 12:06
mat_for_c, в статье говорится о времени процесса - т.е. о том времени, которое процесс занимал процессор. Оно точнее отражает время выполнения программы в многозадачной системе по сравнению с системным временем.

Функция clock возвращает количество тиков процессора. Т.е. если параллельно выполнялось два потока и время первого N, второго - K, то с использованием функции clock получим N+K.

Ну выше уже написали, что в openmp есть функция для измерения времени.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
14.05.2013, 18:47  [ТС]
lazybiz, а правильно ли я понимаю, что небольшие циклы распараллеливать смысла нет? скажем в вашем примере я j изменял до 1000 и при использовании omp работало только медленнее...
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
14.05.2013, 21:54
Цитата Сообщение от mat_for_c Посмотреть сообщение
а правильно ли я понимаю, что небольшие циклы распараллеливать смысла нет? скажем в вашем примере я j изменял до 1000 и при использовании omp работало только медленнее...
Внутренний цикл с переменной j не распараллеливается. Поэтому, скорее всего, вы меня поняли не правильно.
В данном примере распараллеливается только цикл с переменной i. Поэтому, если у цикла как минимум 2 итерации, то есть смысл его распараллелить.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
14.05.2013, 22:12  [ТС]
Цитата Сообщение от lazybiz Посмотреть сообщение
Внутренний цикл с переменной j не распараллеливается. Поэтому, скорее всего, вы меня поняли не правильно.
Я параллелил внешний цикл, но при условии, что j меняется до 1000, а не до 1000000. При этом время работы ухудшалось. Попробуйте пожалуйста проделать то же самое и дайте ответ, какие у Вас результаты и что Вы думаете по этому поводу.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
14.05.2013, 22:32
У меня с 0 <= j < 1000, независимо от того, использую я OpenMP или нет, результат времени == 0. Т.е. это слишком "слабый" цикл.
Я понял что вы имеете в виду. Разумеется, что если вам заранее известно, что цикл занимает очень мало процессорного времени, то нет смысла его распаралелливать.
1
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
15.05.2013, 00:07
разные алгоритмы параллелятся с разной эффективностью. Тут смотреть как оно все масштабируется, что,
что там со всякими кеш промахами, какова нагрузка на шину данных и прочее.
Вот пример тестиков немного разных циклов, запущенных в ДЕБАГЕ 12 студии (в релизе совсем другие цифры, т.к. код другой и распараллелилось соответственно по другому):


Max threads = 8

###################################
Test1:
serial time = 0.00319136
parallel time = 0.0707065
serial/parallel = 0.0451353

###################################
Test2:
serial time = 3.358
parallel time = 1.0248
serial/parallel = 3.27672

###################################
Test3:
serial time = 2.45181
parallel time = 0.722106
serial/parallel = 3.39536

Press any key to continue . . .


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include <omp.h>
 
#include <vector>
#include <iostream>
 
 
class TimeMeasurement
{
public:
  TimeMeasurement()
    : m_begin(omp_get_wtime())
  {
  }
 
  void Reset()
  {
    m_begin = omp_get_wtime();
  }
 
  double Elapsed() const
  {
    return omp_get_wtime() - m_begin;
  }
 
private:
  double m_begin;
};
 
 
typedef std::vector< std::vector<int> > Matrix;
 
Matrix CreateMatrix(unsigned w, unsigned h)
{
  return Matrix(h, std::vector<int>(w, 0));
}
 
 
void Test1()
{
  const unsigned side = 100;
  Matrix a = CreateMatrix(side, side);
  Matrix b = CreateMatrix(side, side);
  Matrix c = CreateMatrix(side, side);
 
  TimeMeasurement timeMeasurement;
 
 
  timeMeasurement.Reset();
 
  for (unsigned i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      c[i][j] += a[i][j] * b[i][j];
    }
  }
 
  const double serialTime = timeMeasurement.Elapsed();
 
 
  timeMeasurement.Reset();
 
 
  #pragma omp parallel for
  for (int i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      c[i][j] = a[i][j] * b[i][j];
    }
  }
 
  const double parallelTime = timeMeasurement.Elapsed();
 
  std::cout << "###################################" << std::endl;
  std::cout << "Test1:" << std::endl;
  std::cout << "serial   time   = " << serialTime << std::endl;
  std::cout << "parallel time   = " << parallelTime << std::endl;
  if (parallelTime > 0.0000001)
  {
    std::cout << "serial/parallel = " << serialTime / parallelTime << std::endl;
  }
  std::cout << std::endl;
}
 
void Test2()
{
  const unsigned side = 100;
  Matrix a = CreateMatrix(side, side);
  Matrix b = CreateMatrix(side, side);
  Matrix c = CreateMatrix(side, side);
 
  TimeMeasurement timeMeasurement;
 
 
  timeMeasurement.Reset();
 
  for (unsigned i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      for (int k = 0; k < 1000; ++k)
      {
        c[i][j] = a[i][j] * b[i][j];
      }
    }
  }
 
  const double serialTime = timeMeasurement.Elapsed();
 
 
  timeMeasurement.Reset();
 
 
  #pragma omp parallel for
  for (int i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      for (int k = 0; k < 1000; ++k)
      {
        c[i][j] = a[i][j] * b[i][j];
      }
    }
  }
 
  const double parallelTime = timeMeasurement.Elapsed();
 
  std::cout << "###################################" << std::endl;
  std::cout << "Test2:" << std::endl;
  std::cout << "serial   time   = " << serialTime << std::endl;
  std::cout << "parallel time   = " << parallelTime << std::endl;
  if (parallelTime > 0.0000001)
  {
    std::cout << "serial/parallel = " << serialTime / parallelTime << std::endl;
  }
  std::cout << std::endl;
}
 
void Test3()
{
  const unsigned side = 100;
  Matrix a = CreateMatrix(side, side);
  Matrix b = CreateMatrix(side, side);
  Matrix c = CreateMatrix(side, side);
 
  TimeMeasurement timeMeasurement;
 
 
  timeMeasurement.Reset();
 
  for (unsigned i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      const int aa = a[i][j];
      const int bb = b[i][j];
      int cc = 0;
      for (int k = 0; k < 100000; ++k)
      {
        cc += aa * bb;
      }
      c[i][j] = cc;
    }
  }
 
  const double serialTime = timeMeasurement.Elapsed();
 
 
  timeMeasurement.Reset();
 
 
  #pragma omp parallel for
  for (int i = 0; i < side; ++i)
  {
    for (unsigned j = 0; j < side; ++j)
    {
      const int aa = a[i][j];
      const int bb = b[i][j];
      int cc = 0;
      for (int k = 0; k < 100000; ++k)
      {
        cc += aa * bb;
      }
      c[i][j] = cc;
    }
  }
 
  const double parallelTime = timeMeasurement.Elapsed();
 
  std::cout << "###################################" << std::endl;
  std::cout << "Test3:" << std::endl;
  std::cout << "serial   time   = " << serialTime << std::endl;
  std::cout << "parallel time   = " << parallelTime << std::endl;
  if (parallelTime > 0.0000001)
  {
    std::cout << "serial/parallel = " << serialTime / parallelTime << std::endl;
  }
  std::cout << std::endl;
}
 
int main()
{
  std::cout << "Max threads = " << omp_get_max_threads() << std::endl << std::endl;
  Test1();
  Test2();
  Test3();
  return 0;
}
1
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
15.05.2013, 00:59  [ТС]
Цитата Сообщение от DU Посмотреть сообщение
в релизе совсем другие цифры, т.к. код другой и распараллелилось соответственно по другому
прикольно... в релизе через omp быстрее отработал 1 тест, а остальные остались почти такими же, как без omp.
так это что получается? если делать релизную версию, то там только для малых входных данных распараллеливание хорошо работает?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.05.2013, 00:59
Помогаю со студенческими работами здесь

Распараллеливание вычислений
Вычисляю произведение матриц несколькими потоками (количество задаётся пользователем). Потоки &quot;засыпают&quot; на 1 мс. При...

Распараллеливание программы
Помогите эту последовательную программу распараллелить на параллельных 2 процесса. #include &lt;iostream&gt; #include&lt;thread&gt; ...

Распараллеливание вычислений
Здравствуйте. Может кто сможет подсказать как мне решить следующую задачу: необходимо распараллелить следующий последовательный код:...

Странное распараллеливание
Добрый вечер, коллеги. У меня следующая проблема. Преподаватель сказал распараллелить программу, обрабатывающую изображения в папке....

Распараллеливание циклов
Доброго времени суток. Возникла необходимость распараллелить один численный алгоритм средствами OpenMP. В частности в этом алгоритме...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru