Форум программистов, компьютерный форум CyberForum.ru

OpenMP и SIMD - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Перебрать все возможные комбинации трех чисел от нуля до двух http://www.cyberforum.ru/cpp-beginners/thread1751285.html
Здравствуйте, помогите, пожалуйста, разобраться с темой (лучше всего написать код, а то на словах вроде понятно, но код всё же лучше) Задача: перебрать все возможные комбинации трех чисел (тип данных int) от нуля до двух. Примеры комбинаций: 0 0 0 0 0 1 0 1 1 1 1 1 2 1 0 1 0 1 2 2 2
C++ Последний элемент каждой строки заменить средним из отрицательных чисел строки (На С++) Преобразовать исходную матрицу A(MxN) так, чтобы последний элемент каждой строки был заменен среднем арифметическим отрицательных чисел http://www.cyberforum.ru/cpp-beginners/thread1751231.html
C++ Найти строки матрицы, в которых число 3 встречается два раза.
(На С++) Матрицу 10x12 заполнить случайными числами от 0 до 10. Вывести на экран саму матрицу и номера строк, в которых число 3 встречается два раза.
C++ Задача о четырех правильных цифрах
дано четыре правильных цифр
C++ Посчитать количество слов в итоговой строке, начинающихся с гласной буквы http://www.cyberforum.ru/cpp-beginners/thread1751215.html
Две строки инициализировать в программе, третью – ввести с клавиату- ры. Сформировать из них новую строку по следующему алгоритму: сначала со- единить строки в порядке возрастания их длины, затем исключить из нее первое и среднее слова. Посчитать количество слов в итоговой строке, начинающихся с гласной буквы.
C++ Преобразовать строку, удалив пробелы, и разделить слова одиночной "звёздочкой" Дана строка слов, разделенных пробелами. Между словами может быть несколько пробелов, в начале и конце строки также могут быть пробелы. Требуется преобразовать строку так, чтобы в ее начале и конце пробелов не было, а слова были разделены одиночным символом "*" (звездочка). подробнее

Показать сообщение отдельно
Saky
0 / 0 / 0
Регистрация: 16.12.2015
Сообщений: 32
01.06.2016, 09:59     OpenMP и SIMD
Добрый день. Не могу исправить код, чтобы использовалось 4 ядра, а не 1. В функцию proizv нужно добавить распараллеливание вычислений с помощью 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
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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctime>
#include <locale.h>
#include <xmmintrin.h>
 
void create(double *mas, int x) {  //создание матрицы
    for (int i = 0; i < x; i++)
        for (int j = 0; j < x; j++) {
            *(mas + i*x + j) = rand() % 10 + 1;
        }
}
 
void transp(double *mas, int x) {  //транспонирование
    double a;
    for (int i = 0; i < x; i++)
        for (int j = i; j < x; j++) {
            a = mas[j*x + i];
            mas[j*x + i] = mas[i*x + j];
            mas[i*x + j] = a;
        }
}
 
double *proizv(double *mas1, double*mas2, int x) {  //произведение после транспонирования
    double *mas3; float sum;
    __m128 *a, *b;
    __m128 c, d;
    a = (__m128 *)mas1;
    b = (__m128 *)mas2;
    mas3 = (double *)_mm_malloc(x*x*sizeof(double), 16);
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {
            d = _mm_set_ps1(0);
            for (int k = 0; k < (x / 4); k++) {
                c = _mm_mul_ps(a[i*x / 4 + k], b[j*x / 4 + k]);
                d = _mm_add_ps(d, c);
            }
            c = _mm_movehl_ps(c, d);
            d = _mm_add_ps(d, c);
            c = _mm_shuffle_ps(d, d, 1);
            d = _mm_add_ss(d, c);
            _mm_store_ss(&sum, d);
            mas3[i*x + j] = sum;
        }
    }
    return mas3;
}
 
int main() {
    srand(time(0));
    int i, x;
    double *mas1, *mas2, *mas3;
    float start_time, end_time;
    printf("Vvedite razmernost' matric\n");
    scanf("%d", &x);
    mas1 = (double *)_mm_malloc(x*x*sizeof(double), 16);
    mas2 = (double *)_mm_malloc(x*x*sizeof(double), 16);
    create(mas1, x);
    create(mas2, x);
    transp(mas2, x);
    start_time = clock();
    mas3 = proizv(mas1, mas2, x);
    end_time = clock();
    float search_time = (end_time - start_time) / 1000;
    printf("runtime = %.1f", search_time);
    _mm_free(mas1);
    _mm_free(mas2);
    _mm_free(mas3);
    _getch();
}
Добавлено через 10 минут
Пыталась изменить на это:
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
double *proizv(double *mas1, double*mas2, int x) {  //произведение после транспонирования
    double *mas3; float sum;
    __m128 *a, *b;
    __m128 c, d;
    a = (__m128 *)mas1;
    b = (__m128 *)mas2;
    mas3 = (double *)_mm_malloc(x*x*sizeof(double), 16);
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {
            d = _mm_set_ps1(0);
#pragma omp parallel
            {
#pragma omp for
                for (int k = 0; k < (x / 4); k++) {
                    c = _mm_mul_ps(a[i*x / 4 + k], b[j*x / 4 + k]);
                    d = _mm_add_ps(d, c);
                }
            }
            c = _mm_movehl_ps(c, d);
            d = _mm_add_ps(d, c);
            c = _mm_shuffle_ps(d, d, 1);
            d = _mm_add_ss(d, c);
            _mm_store_ss(&sum, d);
            mas3[i*x + j] = sum;
        }
    }
    return mas3;
}
Но время выполнения с 5 секунд увеличивается до 18

Добавлено через 12 минут
При подобном варианте:
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
double *proizv(double *mas1, double*mas2, int x) {  //произведение после транспонирования
    double *mas3; float sum; int i, j;
    __m128 *a, *b;
    __m128 c, d;
    a = (__m128 *)mas1;
    b = (__m128 *)mas2;
    mas3 = (double *)_mm_malloc(x*x*sizeof(double), 16);
#pragma omp parallel
    {
#pragma omp for
        for (i = 0; i < x; i++) {
            for (j = 0; j < x; j++) {
                d = _mm_set_ps1(0);
                for (int k = 0; k < (x / 4); k++) {
                    c = _mm_mul_ps(a[i*x / 4 + k], b[j*x / 4 + k]);
                    d = _mm_add_ps(d, c);
                }
            }
            c = _mm_movehl_ps(c, d);
            d = _mm_add_ps(d, c);
            c = _mm_shuffle_ps(d, d, 1);
            d = _mm_add_ss(d, c);
            _mm_store_ss(&sum, d);
            mas3[i*x + j] = sum;
        }
    }
    return mas3;
}
Выполняется 1,4 секунды, но заканчивается ошибкой
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 23:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru