Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
denisberton
1

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

02.08.2012, 02:50. Просмотров 1173. Ответов 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)
            }
        
        }
    
    }
Честно говоря, метод подсмотрел тут.

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

Не могли бы вы посоветовать как можно распараллелить программу? Возможно, здесь совсем несложно, а я все усложняю?
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2012, 02:50
Ответы с готовыми решениями:

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

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

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

Необходимо написать программу для решения уравнений
помогите написать программу для решения.

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.08.2012, 02:50

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

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

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

Написать программу для решения системы уравнений методом Гаусса (c++)
Добрый вечер! Нужно написать программу для решения системы уравнений методом Гаусса. Уравнений...

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


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

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

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