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

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

Войти
Регистрация
Восстановить пароль
 
Kapex
15 / 15 / 4
Регистрация: 11.11.2014
Сообщений: 121
#1

Передача в поток многомерных массивов по указателю - C++

30.09.2016, 16:39. Просмотров 287. Ответов 5
Метки нет (Все метки)

Доброго всем времени суток.

У меня возникло непонимание того, как можно передать двумерный (многомерный) массив в поток. Пока это выглядит вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void worker (void* array2d, int size1, int size2){
       int ** arrayToWork = reinterpret_cast<int**> (array2d);
       
       for (int i = 0; i < size1; ++i)
            for (int j = 0; j < size2; ++j)
                  read_and_process(array2d[i][j]);
 
      /* do usefull stuff */
}
int main(){
     int  arr2d[size1][size2];
           /* fill in the arr2d*/
 
     vector<thread> poolThreads;
     for (int iThread = 0; iThread < 4; iThread++)
          pollThreads.push_back(thread(worker,  reinterpret_cast<void*> (arr2d), size1, size2));
     for (int iThread = 0; iThread < 4; iThread++)
          pollThreads[iThread].join();
        
   
  return 0;
}
Есть ли какой-нибудь более правильный способ передачи двумерных (многомерных) массивов в поток без использования приведений?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2016, 16:39
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Передача в поток многомерных массивов по указателю (C++):

Передача многомерных массивов в функцию - C++
Привет. Почему при передаче многомерного массива в функцию необходимо обязательно указывать измерения, кроме первого? Зачем это нужно? ...

Обработка многомерных массивов - C++
Создать многомерный массив 3x3 элементов.Сделать Разность по горизонтали. Три полученых результата вывести на экран.

указатели многомерных массивов - C++
как в программе воспользоваться указателями? пишу по конспекту, но что то вообще ничего не получается #include &lt;iostream&gt; #include...

Обработка многомерных массивов - C++
Создать многомерный массив 4x4.Вывести на экран минимальное значение многомерного массива.

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

Программирование обработки многомерных массивов - C++
Дана целочисленная прямоугольная матрица. Определить: количество строк, содержащих хотя бы один нулевой элемент; номер столбца в котором...

5
DrOffset
7376 / 4453 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
30.09.2016, 19:16 #2
Kapex, ну например так:
C++
1
2
3
4
5
6
7
8
9
10
11
size_t const size1 = 4;
size_t const size2 = 5;
 
void worker (int (*array2d)[size2], int size1){
      
       for (int i = 0; i < size1; ++i)
            for (int j = 0; j < size2; ++j)
                  read_and_process(array2d[i][j]);
 
      /* do usefull stuff */
}
C++
1
pollThreads.push_back(thread(worker, arr2d, size1));
Но в целом все зависит от конечной цели. В том числе и "правильность".

Добавлено через 45 минут
Kapex, в принципе, если бы мне понадобилось (если бы) что-то подобное, то я бы сделал так:
Кликните здесь для просмотра всего текста
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
template <typename T>
class LightArray2d
{
public:
    LightArray2d(size_t r, size_t c)
        : m_rows(r)
        , m_columns(c)
        , m_data(new T[r * c])
    { }
    LightArray2d(LightArray2d && x)
        : m_columns(x.m_columns)
        , m_rows(x.m_rows)
        , m_data(std::move(x.m_data))
    { }
    
    T * operator[](size_t i)
    {
        return &m_data[i * m_columns];
    }
    T const * operator[](size_t i) const
    {
        return &m_data[i * m_columns];
    }
    
    T const & operator()(size_t i, size_t j) const
    {
        return m_data[i * m_columns + j];
    }
    T & operator()(size_t i, size_t j)
    {
        return m_data[i * m_columns + j];
    }                          
                      
    size_t columns() const
    {
        return m_columns;
    }
    size_t rows() const
    {
        return m_rows;
    }
    
    T * begin() 
    { 
        return &m_data[0]; 
    }
    T * end() 
    { 
        return &m_data[m_rows * m_columns]; 
    }
    T const * begin() const
    { 
        return &m_data[0]; 
    }
    T const * end() const
    { 
        return &m_data[m_rows * m_columns]; 
    }
   
private:
    size_t const m_rows;
    size_t const m_columns;
 
    std::unique_ptr<T[]> m_data;
};

или так (если размерности известны на этапе компиляции):
Кликните здесь для просмотра всего текста
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
// Версия без динамической памяти (для размеров, известных на этапе компиляции)
template <typename T, size_t R, size_t C>
class LightArray2d
{
public:
    T * operator[](size_t i)
    {
        return &m_data[i * C];
    }
    T const * operator[](size_t i) const
    {
        return &m_data[i * C];
    }
    
    T const & operator()(size_t i, size_t j) const
    {
        return m_data[i * C + j];
    }
    T & operator()(size_t i, size_t j)
    {
        return m_data[i * C + j];
    }                          
                      
    size_t columns() const
    {
        return C;
    }
    size_t rows() const
    {
        return R;
    }
    
    T * begin() 
    { 
        return &m_data[0]; 
    }
    T * end() 
    { 
        return &m_data[R * C]; 
    }
    T const * begin() const
    { 
        return &m_data[0]; 
    }
    T const * end() const
    { 
        return &m_data[R * C]; 
    }
   
private:
    std::array<T, R * C> m_data;
};

И потом спокойно бы работал с этим так:
Кликните здесь для просмотра всего текста
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
//void worker(LightArray2d<int, 5, 6> const & array2d)
void worker(LightArray2d<int> const & array2d)
{
    // var [1] 
    for(size_t i = 0; i < array2d.rows(); ++i)
    {
        for(size_t j = 0; j < array2d.columns(); ++j)
        {
            // Это исключительно для визуализации, конечно же в реальности из потока в консоль лучше ничего не писать.
            std::cout << array2d[i][j] << ' '; 
        }
    }
    std::cout << std::endl;
    // var [2]
    for(size_t i = 0; i < array2d.rows(); ++i)
    {
        for(size_t j = 0; j < array2d.columns(); ++j)
        {
            std::cout << array2d(i, j) << ' ';
        }
    }
    std::cout << std::endl;
    // var [3]
    for(int a : array2d)
    {
        std::cout << a << ' ';
    }
    /* do usefull stuff */
}
 
int main() {
    LightArray2d<int> arr2d(5, 6);
    //LightArray2d<int, 5, 6> arr2d;
    
    /* fill in the arr2d*/
    int c = 0;
    std::generate(arr2d.begin(), arr2d.end(), [&c](){ return ++c; });
    
    enum { ThreadsCount = 1 }; // 1, чтобы в демопримере не испортить вывод.
    
    vector<thread> poolThreads;
    for(int iThread = 0; iThread < ThreadsCount; iThread++)
    {
        poolThreads.emplace_back(thread(worker, std::ref(arr2d)));
    }
    
    for(int iThread = 0; iThread < ThreadsCount; iThread++)
    {
        poolThreads[iThread].join();
    }
}

Онлайн демопример: http://rextester.com/QSCDC23483
4
nmcf
30.09.2016, 20:11
  #3

Не по теме:

DrOffset, как-то длинновато вышло в сравнении с его примером.

0
DrOffset
30.09.2016, 20:21
  #4

Не по теме:

Цитата Сообщение от nmcf Посмотреть сообщение
как-то длинновато вышло в сравнении с его примером.
С учетом того, что подобный класс выносится в библиотечку проекта и использует потом всюду, длина компенсируется.
Так-то, если ты возьмешь, к примеру, std::array и вставишь его код к себе в проект, то тоже получится много.
Если это лаба, и ему нужно это в одном месте, то уж извините, можно тогда игнорировать этот пост.

0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
30.09.2016, 22:50 #5
Kapex, вот интересная ещё инфа
Передача двумерного массива в функцию. Ошибка "invalid types for array subscript"
Штука в том, что массив C++ внутренне всегда одномерен. То есть, индексы можно пересчитывать, а указатель кастить. Вот вариант - вырви-глаз:
Кликните здесь для просмотра всего текста
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
#include <iostream>
using namespace std;
template<class T, size_t m, size_t n>
void print_2D_arr(T (*arr)[n])
{
for(size_t i = 0; i < m ; ++i)
{
for(size_t j = 0; j < n ; ++j)
cout<<arr[i][j]<<' ';
cout<<endl;
}
}
 
int main(int argc, char* argv[])
{
int a[2][3]={{1,2,3},{4,5,6}};
double b[2][3]={{1.23,2.34,3.45},{4.56,5.67,6.78}};
print_2D_arr<int, 2, 3>(a);
cout<<endl;
print_2D_arr<double, 2, 3>(b);
cout<<endl;
system("pause");
return 0;
}

А вектор векторов чем плох?
0
Kapex
15 / 15 / 4
Регистрация: 11.11.2014
Сообщений: 121
05.10.2016, 12:14  [ТС] #6
DrOffset, спасибо большое. Попробую. На этапе компиляции, к сожалению, размер не известен, поэтому буду пробовать первый вариант. Но я сейчас вижу бОльшие проблемы в размере данных: хочется натравить несколько потоков на 300 Мб данных (данные хорошо обрабатываются в параллель), причём первоначальная идея был наплодить потоков и каждому потоку отдать кусок: первому -- первые 10 Мб, второму - вторые 10 Мб и т.д. Но при такой организации, чую, потоки уже в L3 будут пузиками толкаться, и я не получу пропорционального выигрыша в скорости обработки данных, ибо всё происходит на одной машине с одним процом и общим кэшем.

IGPIGP, вектор векторов хорош, но я пока не научился просить конструктор вектора аллоцировать данные внутри, выровненные по границе. К тому же я не знаю, как будет вести себя gcc во время оптимизации вектора векторов.
0
05.10.2016, 12:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.10.2016, 12:14
Привет! Вот еще темы с ответами:

Редактор многомерных динамических массивов - C++
!!! Пишу в Microsoft Visual Studio -&gt;Win32 Console application -&gt;C++. !!! Помогите мне пожалуйста...

Быстрая инициализация многомерных массивов - C++
Доброго времени суток. Работаю на QT Creator в связке с MinGW 32 Проблемы в общем то и нет, вопрос скорее по оптимизации. Какой самый...

Pthread, поток, передающий значение по указателю - C++
Создаётся поток, передающий значение по указателю: pthread_create (&amp;pthread_id1, NULL, my_thread,(void *)arr); pthread_create...

Шестнадцатеричный вывод WORD и DWORD в поток без приведения к указателю - C++
Как сделать? Есть ли для этого потоковый манипулятор? Желательно, чтоб цифры A-F были в верхнем регистре и выводились старшие не значащие...


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

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

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