0 / 0 / 0
Регистрация: 10.09.2012
Сообщений: 31
1

C++ MPI выделение потоков

14.01.2014, 21:45. Показов 3274. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, я к вам с немного нубским вопросом. Написал вот такой код:

Кликните здесь для просмотра всего текста
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <vector>
#include <ctime>
#include <mpi.h>
using namespace std;
 
void FillMatrix(const int n, const int m, int** mtrx, int* ivc);
void ReceiveMatrix(const int n, const int m, int** mtrx, int* rvc);
void PrintRcv(int vec[], int n, int &rng, int operation);
void sortVc(int* vector, int count);
 
void main(int argc, char **argv)
{
    setlocale(LC_ALL,"Russian");
    srand(time(NULL));
    int size, range;
    const int n=7;
    const int m=6;
    const int msize = m*n;
 
    int scount;
 
    int** matrix = new int* [n];
    int ivc[msize];
    int* rcv = new int[msize];
    for(unsigned i = 0; i < n; i++)
        matrix[i] = new int [m];
    MPI_Init(&argc, &argv);
    MPI_Comm_size (MPI_COMM_WORLD, &size);
    MPI_Comm_rank (MPI_COMM_WORLD, &range);
    scount = msize/size;
    int* tvc = new int[scount];
    if(range==0)
    {
        FillMatrix(n, m, matrix, ivc);      
    }
    
    if((msize%size)!=0)
    {
        scount++;
    }
    MPI_Scatter(&ivc[0],scount, MPI_INT, &tvc[0], scount, MPI_INT, 0, MPI_COMM_WORLD);
    PrintRcv(tvc, scount, range, 1);
    MPI_Barrier(MPI_COMM_WORLD);
    sortVc(tvc, scount);
    PrintRcv(tvc, scount, range, 2);
    //GATHERING HERE!
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Gather(&tvc[0], scount, MPI_INT, &rcv[0], scount, MPI_INT, 0, MPI_COMM_WORLD);
    
    MPI_Finalize();
    if(range == 0)
    {
        ReceiveMatrix(n, m, matrix, rcv);
    }
}
 
void FillMatrix(const int n, const int m, int** mtrx, int* ivc)
{
    int rc=0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            mtrx[i][j] = rand() % 64;
            cout<<"["<<i<<"]["<<j<<"]="<<mtrx[i][j]<<"\t";
            ivc[rc]=mtrx[i][j];
            rc++;
        }
        cout<<endl;
    }
}
 
void PrintRcv(int vec[], int n, int &rng, int operation)
{
    if(operation==1)
        cout<<"   Scattered Thread # "<<rng<<": ";
    if(operation==2)
        cout<<"   Sorting Thread # "<<rng<<": ";
    for(int i=0;i<n;i++)
    {
        cout.width(3);
        cout<<vec[i]<<" ";
    }
    cout<<endl;
}
 
void sortVc(int* vector, int count)
{
    for(int i = 0; i < count; i++)
    {
        for(int j = 0; j < count; j++)
            if(vector[i] < vector[j])
            {
                int tmp = vector[i];
                vector[i]=vector[j];
                vector[j]=tmp;
            }
    }
}
 
void ReceiveMatrix(const int n, const int m, int** mtrx, int* rvc)
{
    int rc = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            mtrx[i][j] = rvc[rc];
            rc++;
            cout<<"["<<i<<"]["<<j<<"]="<<mtrx[i][j]<<"\t";
        }
        cout<<endl;
    }
}


Код сортирует элементы в строках матрицы, но работает немного некорректно. Требуется, чтобы при любом количестве потоков сортировка элементов строки всегда работала правильно, а в моем коде она работает только если выделить количество потоков, кратное (лучше равное) количеству строк в матрице, иначе оно распределяет все элементы по количеству текущих потоков, и сортировка получается в корне неправильной. Пытался переделать так, чтобы потоки заново выделялись для обработки оставшихся строк - не вышло. Собственно, прошу помощи. Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2014, 21:45
Ответы с готовыми решениями:

Область видимости общей переменной для потоков + закрытие потоков
Есть два вопроса про потоки. Первый. Как можно сделать общую переменную для основного потока и...

Замедление работы потоков если запущено несколько потоков
Есть отдельный поток который движет красным квадратом. Он каждую миллисекунду меняет положение...

Создание и завершение процессов и потоков. Приоритеты выполнения потоков
Здравствуйте. Буду очень раз если поможете понять,что конкретно нужно сделать в вот этом...

Разработать программу, генерирующую n потоков в пуле потоков CLR
Добрый вечер. Решил поделать старые лабораторные, которые мне уже давно нужно было сдавать, но...

1
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
17.01.2014, 00:05 2
Mellotron, если я вас правильно понял, то, например, так:
Групповыми операциями, как у вас, похоже, будет сложнее, так как придется динамически менять группу и создавать коммутатор.
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
int main(int argc, char **argv)
{
  int size, range;
  const int n=7;
  const int m=6;
  const int msize = m*n;
 
  int** matrix = new int* [n];
  for(unsigned i = 0; i < n; i++) matrix[i] = new int [m];
  int ivc[msize];
  int* rcv = new int[msize];
  int* tvc = new int[n];
  MPI_Init(&argc, &argv);
  MPI_Comm_size (MPI_COMM_WORLD, &size);
  MPI_Comm_rank (MPI_COMM_WORLD, &range);
  if (!range) FillMatrix(n, m, matrix, ivc);
 
  MPI_Status st= {0};
  MPI_Barrier(MPI_COMM_WORLD);
  int count= 0;
  if(range==0) for (int k= 0; k < n + size - 1; k++) {
      MPI_Recv (tvc, m, MPI_INT, MPI_ANY_SOURCE,  MPI_ANY_TAG, MPI_COMM_WORLD, &st);
      MPI_Get_count (&st, MPI_INT,&count);
      if (count == m) memcpy (rcv + m * st.MPI_TAG, tvc, m * sizeof (int));
      count=  (k < n) ? m : 0;
      MPI_Send (ivc + k * m, count, MPI_INT, st.MPI_SOURCE, k, MPI_COMM_WORLD);
  }
  else for (;;) {
      MPI_Send (tvc, count, MPI_INT, 0, st.MPI_TAG, MPI_COMM_WORLD);
      MPI_Recv (tvc, m, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &st);
      MPI_Get_count (&st, MPI_INT,&count);
      if (!count) break;
      PrintRcv(tvc, m, range, 1);
      sortVc(tvc, m);
      PrintRcv(tvc, m, range, 2);
  }
  MPI_Finalize();
 
  if(range == 0) ReceiveMatrix(n, m, matrix, rcv);
  return 0;
}
1
17.01.2014, 00:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2014, 00:05
Помогаю со студенческими работами здесь

Синхронизация потоков на элементарном уровне (переключение потоков)
в общем разбираюсь с потоками, на сколько понял мне нужен lock Вот имеется просто пример ...

Синхронизация потоков: проблема гонки потоков
Есть проблема в синхронизации потоков, которую я не знаю, как решить. Точнее у меня получается...

Общение пхп потоков, есть ли область видимая для всех пхп потоков?
Добрый день форумчане. Суть вопроса такова - сайт работает с апи вк, как известно у вк есть...

Как на cellclick сделать выделение только строки, а выделение столбца отменить
Здравствуйте, проблема такая, программа работает отлично, но я занимаюсь сопровождением ПО. И при...


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

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

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