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

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

Восстановить пароль Регистрация
Другие темы раздела
C++ list http://www.cyberforum.ru/cpp-beginners/thread631904.html
Здравствуйте, уважаемые форумчане. #include <iostream.h> #include <list> #include <conio.h> template <class T> class Array { list<int>_list; public:
C++ Unresolved external symbol, unresolved token Всем привет. У меня тут такое дело: // learncpp.cpp : main project file. #include "stdafx.h" int main() { const int LENGTH = 5; setlocale(LC_ALL,"Russian"); http://www.cyberforum.ru/cpp-beginners/thread631870.html
bool в g++ C++
При компиляции программы в g++ она не выдают никаких ошибок, но во время выполнения ее выкидывает. #include <iostream> using namespace std; int main() { bool a = true; cout << a; return 0; }
Ссылки на книги C++
Нужны ссылки на сайты, где можно в онлайн режиме прочитать книги по С++ для начинающих
C++ Инсталляция библиотеки FLTK http://www.cyberforum.ru/cpp-beginners/thread631832.html
Пытаюсь установить библиотеку fltk, так как написано в учебнике Страуструпа. Но в итоге ========== Построение: успешно: 1, с ошибками: 68, без изменений: 2, пропущено: 0 ========== сплошные сбои. причем количество успешных может меняться, но не сильно. Как сказано, нужно искать файл (fltk.dsw), но в тех папках (vc2005 и vcnet), где предлагается искать, лежат (fltk.sln). Но fltk.dsw в...
C++ Будет программа, написанная через Windows Form Application работать на других ОС? Будет программа, написанная через Windows Form Application работать на других ОС? Я использую Microsoft Visual C++ 2010 подробнее

Показать сообщение отдельно
denisberton
Сообщений: n/a
02.08.2012, 02:50     Распараллелить программу для решения дифференциальных уравнений
Здравствуйте, посетители форума.

Я пробую распараллелить следующий фрагмент кода:
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)
            }
        
        }
    
    }
Честно говоря, метод подсмотрел тут.

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

Не могли бы вы посоветовать как можно распараллелить программу? Возможно, здесь совсем несложно, а я все усложняю?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 02:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru