Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
denisberton
0 / 0 / 0
Регистрация: 29.07.2012
Сообщений: 1
#1

Распараллелить программу для решения дифференциальных уравнений - C++

02.08.2012, 02:50. Просмотров 1018. Ответов 0
Метки нет (Все метки)

Здравствуйте, посетители форума.

Я пробую распараллелить следующий фрагмент кода:
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
    ...
    // начальная инициализация всех значений
    ...
    doubleVec F_vect;
    doubleVec G_plus_vec;
    doubleVec G_minus_vec;
    
    int n, k;
    
    // K iterations
    
    for (k = 1; k <= K; k++) 
    {
        mU[k][0] = u0;
        mG[k][0] = u0;
    }
    
 
    for (k = 1; k <= K; k++) 
    {
        for (n = 1; n <= N; n++) // N subintervals
        {
            double TnNew = T0 + n * deltaT;
            double Tn = TnNew - deltaT; // move to the next interval
            
            F_vect = (oFE.*F) (f, TnNew, Tn, mU[k-1][n-1], IF);
            G_plus_vec = (oFE.*G) (f, TnNew, Tn, mU[k][n-1], IG);
            G_minus_vec = mG[k-1][n]; // get from previous G_plus_vec
            
            mG[k][n] = G_plus_vec;
            
            for (int i = 0; i < size_u; i++)
            {
                // main formula
                F_vect[i] = F_vect[i] + G_plus_vec[i] - G_minus_vec[i];
            }
            
            mU[k][n] = F_vect;
            
        } // for (int n = 1; n <= N; n++)
    
    }
Здесь mU - глобальная матрица. На каждом шаге (k) вычисляется значение U.

Две основные сторчки:

F_vect = (oFE.*F) (f, TnNew, Tn, mU[k-1][n-1], IF);
G_plus_vec = (oFE.*G) (f, TnNew, Tn, mU[k][n-1], IG);

Вычисление функции F занимает обычно много времени.

Я реализовал для многопроцессорной машины (по времени все получилось).
Сделал так:

Корень 1: Вычисляет F, G, U_1_1, отправляет U_1_1 на Корень 2, продолжает вычислять (и отправлять) U_1_2, U_1_3...
Корень 2: Получает U_1_1, Вычисляет F, G, U_2_1, отправляет U_2_1 на Корень 3, поучает U_1_2, вычисляет U_2_2, ...
Корень 3: Получает U_2_1, Вычисляет F, G, U_3_1, отправляет U_3_1 на Корень 4, продолжает вычислять U_3_2, ...
и т. д.


Теперь пробую реализовать многопоточную версию следующим образом:

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
    doubleVec F_vect;
    doubleVec G_plus_vec;
    doubleVec G_minus_vec;
    
    int iam, numt, limit, n, k;
    int isync[NUMBER_OF_THREADS];
    
    // K iterations
    
    for (k = 1; k <= K; k++) 
    {
        mU[k][0] = u0;
        mG[k][0] = u0;
    }
    #pragma omp parallel private (iam, numt, limit, k, F_vect, G_plus_vec, G_minus_vec)
    {
        iam = omp_get_thread_num ();
        numt = omp_get_num_threads ();
        limit = std::min(numt-1, N);
        isync[iam] = 0;
        #pragma omp barrier
        
        for (k = 1; k <= K; k++) 
        {
            if ((iam > 0) && (iam <= limit)) 
            {
                for (;isync[iam-1] == 0;) 
                {
                    #pragma omp flush (isync)
                }
                isync[iam-1] = 0;
                #pragma omp flush (isync)
            }
            
            #pragma omp for schedule(static) nowait
            for (n = 1; n <= N; n++) // N subintervals
            {
                double TnNew = T0 + n * deltaT;
                double Tn = TnNew - deltaT; // move to the next interval
                
                F_vect = (oFE.*F) (f, TnNew, Tn, mU[k-1][n-1], IF);
                G_plus_vec = (oFE.*G) (f, TnNew, Tn, mU[k][n-1], IG);
                G_minus_vec = mG[k-1][n]; // get from previous G_plus_vec
                
                //UGnext[n] = G_plus_vec;
                mG[k][n] = G_plus_vec;
                
                for (int i = 0; i < size_u; i++)
                {
                    // main formula
                    F_vect[i] = F_vect[i] + G_plus_vec[i] - G_minus_vec[i];
                }
                
                mU[k][n] = F_vect;
                
            } // for (int n = 1; n <= N; n++)
            
            if (iam < limit) 
            {
                for (;isync[iam]==1;) 
                {
                    #pragma omp flush (isync)
                }
                isync[iam] = 1;
                
                #pragma omp flush (isync)
            }
        
        }
    
    }
Честно говоря, метод подсмотрел тут.

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

Не могли бы вы посоветовать как можно распараллелить программу? Возможно, здесь совсем несложно, а я все усложняю?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2012, 02:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Распараллелить программу для решения дифференциальных уравнений (C++):

сделать программу для решения дифференциальных уравнений - C++
Нужна сделать программу для решения дифференциальных уравнений 1)(1+x2)dy+ydx=0,y=1 при x=1; 2)y|=tgx*tgy; программу сделать я смогу...

Метод Рунге-Кутта 4 порядка для решения системы дифференциальных уравнений - C++
Имеется код программы, но по не очевидным для меня причинам работает не корректно, во время отладки выдает сообщения типа : Run-Time...

Написать программу для решения уравнений - C++
Не могу сделать прогу на С++. Кто сделает - огромное спасибо. Необходимо выбрать 3 уравнения и написать для них программу на С++. ...

Написать программу для решения системы двух уравнений - C++
не знаю как написать программу вводимы и выводимые данные сопровождать краткими поясняющими текстами для проверки численных значений...

Написать программу для решения системы нелинейных уравнений - C++
Не могу сделать прогу на С++. Кто сделает - огромное спасибо. sin(9x)+cos(7y)-5z*z=10, cos(x)+y-tan(2x)=17, cos(x)+6y-cos(z)=23; ...

Написать программу для решения системы уравнений методом Гаусса (c++) - C++
Добрый вечер! Нужно написать программу для решения системы уравнений методом Гаусса. Уравнений всего два: a11*x1 + a12*x2 = z1...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2012, 02:50
Привет! Вот еще темы с ответами:

Написать программу для решения системы уравнений с пом. матрицы - C++
Добрый день! Очень прошу вашей подсказки в написании моей первой программы для решения системы уравнений с помощью матрицы! Собственно,...

Написал программу для решения квадратных уравнений, но не получается подогнать ее под нужные условия - C++
Дано условие : На вход вашей программе в стандартном вводе даны действительные коэффициенты A, B и C уравнения Ax² + Bx + C = 0. Выведите...

Функция для численного интегрирования системы дифференциальных уравнений методом Рунге - Кутта - C++
Доброго времени суток. У меня есть вот такая задачка: Разработать функцию для численного интегрирования системы дифференциальных...

Составить программу решения системы уравнений - C++
составить программу решения системы уравнений ax+by+c=0 a1x+b1y+d=0


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.