Форум программистов, компьютерный форум, киберфорум
OpenMP
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/40: Рейтинг темы: голосов - 40, средняя оценка - 4.53
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
1

Умножение матриц (g++)

09.12.2020, 14:54. Показов 7976. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется демонстрационный код (умножение матриц). Структура вида:

-Инициализация данных
-Алгоритм без распараллеливания
-Алгоритм с использованием директивы openMP (parallel for)

После каждого из алгоритмов выводится время выполнения.
Компилирую так:

Код
$ g++ fileName -o -matrix -fopenmp
$ ./matrix
Прирост производительности - нулевой. Причем разделение на потоки происходит - достаточно раскомментировать соответствующие строчки и посмотреть вывод. В чем проблема?

Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <cstdio>
#include <ctime>
#include <omp.h>
 
using namespace std;
 
const int n=1000;
double a[n][n];
double b[n][n];
double c[n][n];
 
 
int main(int argc, char *argv[])
{
    /*init*/
    
    for (int i=0; i<n; i++)
    for (int j=0; j<n; j++)
    {
        a[i][j] = (rand() % 100)/100.0+1.0;
        b[i][j] = (rand() % 100)/100.0+1.0;
    }
 
    /*First block (single)*/
    
    long t1 = clock();
    
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++)
        {
            //printf ("iteration %d, thread=%d\n", j, omp_get_thread_num());
            double cc = 0;
            for (int k=0; k<n; k++)
                cc += a[i][k]*b[k][j];
            c[i][j] = cc;
        }
    }
    
    long t2 = clock();
 
    cout<<c[n-1][n-1]<<endl;
    cout<<(t2-t1)/1000.0<<" - total time single (ms)"<<endl;
    
    t1 = clock();
    
    /*Second block (parallel)*/
        
    #pragma omp parallel for
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++)
        {
            //printf ("iteration %d, thread=%d\n", j, omp_get_thread_num());
            double cc = 0;
            for (int k=0; k<n; k++)
                cc += a[i][k]*b[k][j];
            c[i][j] = cc;
        }
    }
    
    t2 = clock();
 
    cout<<c[n-1][n-1]<<endl;
    cout<<(t2-t1)/1000.0<<" - total time parallel (ms)"<<endl;
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.12.2020, 14:54
Ответы с готовыми решениями:

Умножение матриц с использованием OpenMP
Здрасте. Есть следующая задача. Нужно реализировать умножение двух квадратных матриц с...

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

Перемножение матриц, умножение матриц на вектор, сложение матриц
Помогите пожалуйста написать программу, которая производит основные действия с матрицами...

Процедуры. Умножение матриц, векторов. Скалярное умножение. Надо найти ошибку
Дано 6-элементные действительные векторы и квадратные матрицы A,B,C 6-ого порядка. Найти...

Транспонирование, умножение матриц, сложение матриц Реализовать в одной программере
транспонирование, умножение матриц, сложение матриц; B^3-A^T Реализовать в одной программере....

6
1566 / 1492 / 248
Регистрация: 19.02.2010
Сообщений: 4,048
09.12.2020, 16:54 2
Цитата Сообщение от Ksardas_178 Посмотреть сообщение
В чем проблема?
Проблема совсем не в этом. Проблема в том, что пытаетесь распараллелить говнокод.
А именно - хреновый паттерн доступа к памяти (при обращении к элементам матрицы b).
Перед перемножением транспонируйте матрицу b (т.е. в коде затем будет умножаться строка из a на строку из bT) - и перемножение ускорится в разы даже без распараллеливания.
Для более быстрого проведения эксперимента можете даже не транспонировать - а предположить, что матрица b уже транспонирована, и просто переставить в умножающей строке индексы (будет *b[j][k]).
Ждём-с цифр времени выполнения исходного варианта кода и предлагаемого транспонированного
1
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
09.12.2020, 19:06  [ТС] 3
Цитата Сообщение от VTsaregorodtsev Посмотреть сообщение
Перед перемножением транспонируйте матрицу b (т.е. в коде затем будет умножаться строка из a на строку из bT) - и перемножение ускорится в разы даже без распараллеливания.
Да, встречал в одном примере такой эффект. Что-то про опережающее считывание в кэш процессора. Даже в этой программе пробовал. Сейчас написал еще раз, добавил двойной for для транспонирования, вынес за расчет времени выполнения. В этом случае - да, есть "минус" по времени. Параллельный код все еще жрет столько же, сколько нераспараллеленный.

Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <cstdio>
#include <ctime>
#include <omp.h>
 
using namespace std;
 
const int n=1000;
double a[n][n];
double b[n][n];
double c[n][n];
 
 
int main(int argc, char *argv[])
{
    /*init*/
    
    for (int i=0; i<n; i++)
    for (int j=0; j<n; j++)
    {
        a[i][j] = (rand() % 100)/100.0+1.0;
        b[i][j] = (rand() % 100)/100.0+1.0;
    }
    
    
    for (int i=0; i<n; i++) 
    for (int j=0; j<i; j++) 
        swap(b[i,j],b[j,i]);
 
    /*First block (single)*/
    
    long t1 = clock();
    
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++)
        {
            //printf ("iteration %d, thread=%d\n", j, omp_get_thread_num());
            double cc = 0;
            for (int k=0; k<n; k++)
                cc += a[i][k]*b[j][k];
            c[i][j] = cc;
        }
    }
    
    long t2 = clock();
 
    cout<<c[n-1][n-1]<<endl;
    cout<<(t2-t1)/1000.0<<" - total time single (ms)"<<endl;
    
    /*Second block (parallel)*/
        
    t1 = clock();
    
    #pragma omp parallel for
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++)
        {
            //printf ("iteration %d, thread=%d\n", j, omp_get_thread_num());
            double cc = 0;
            for (int k=0; k<n; k++)
                cc += a[i][k]*b[j][k];
            c[i][j] = cc;
        }
    }
    
    t2 = clock();
 
    cout<<c[n-1][n-1]<<endl;
    cout<<(t2-t1)/1000.0<<" - total time parallel (ms)"<<endl;
    return 0;
}
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
09.12.2020, 20:00 4
Цитата Сообщение от Ksardas_178 Посмотреть сообщение
Параллельный код все еще жрет столько же, сколько нераспараллеленный.
У меня твой код показывает
2260.33
1.291 - total time single (ms)
2260.33
0.25 - total time parallel (ms)
Добавлено через 1 минуту
И в дебаге примерно такое же соотношение

Добавлено через 37 секунд
Ты наверное openmp не включил в опциях компилятора

Добавлено через 4 минуты
И где ты проверяешь, на локальном компе?
1
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
09.12.2020, 20:07  [ТС] 5
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ты наверное openmp не включил в опциях компилятора
Все подключаемые опции привел в первом сообщении.
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
И где ты проверяешь, на локальном компе?
Да, на своем локальном и у сокурсника.
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
09.12.2020, 20:11 6
Цитата Сообщение от Ksardas_178 Посмотреть сообщение
Да, на своем локальном и у сокурсника.
Ну, в Visual C++ всё работает нормально, я показал. Проверить на gcc возможности нет, но проблема, скорее всего не в коде
1
58 / 42 / 21
Регистрация: 01.01.2018
Сообщений: 273
09.12.2020, 22:53  [ТС] 7
Проблема была в использованной библиотеке для подсчета времени выполнения. Как мне объяснили, clock() выдает суммарное время работы всех потоков. Заменили на chrono - все заработало.
0
09.12.2020, 22:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.12.2020, 22:53
Помогаю со студенческими работами здесь

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

Написать программу, выполняющую функции калькулятора матриц (транспонирование матрицы, умножение матриц)
Работа с функциями В программе должна быть не меньше 2-3 функций

Умножение треугольных матриц«Методы обработки разреженных матриц»
Нужно перемножить треугольные матрицы в обычном виде и в свёрнутом. С обычным проблем нет. Доступ...

Чтение матриц с внешнего файла, умножение матриц...
Вот не могу составить программу... Необходимо считать матрицы А и В с внешнего файла (input)....

Умножение матриц (не работает для неквадратных матриц)
Доброго времени суток. Написал код для перемножения двух матриц. При вводе квадратной матрицы всё...

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru