Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/34: Рейтинг темы: голосов - 34, средняя оценка - 4.56
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
1

Многопоточность при сортировке массивов

13.04.2014, 22:11. Показов 6620. Ответов 84
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Уважаемые, столкнулся с ситуацией, имею 3 массива, содержимое которых одинаково (координаты точек в 3д пространстве), произвожу сортировку каждого массива по определенному измерению (x, y, z), хотел спросить, можно ли как-то ускорить процесс, возникла идея многопоточности (т.е. одновременно выполнять сортировку 3-х массивов), но я не уверен что я корректно мыслю т.к. не разу не сталкивался с многопоточностью, подскажите как правильно ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.04.2014, 22:11
Ответы с готовыми решениями:

Не могу найти ошибку при сортировке массивов
Даны два числа n и m и два упорядоченных по неубыванию массива A<=A<=....<=A и B<=B<=....<=B....

Почему программа падает при сортировке массивов больших размерностей
Добрый день! Подскажите почему прога крашится при размере массива 10000, при значении 1000 все...

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

Обработка массивов и многопоточность
Здравствуйте. Одна из функций обрабатывает массивы и постоянно изменяет переменные, записанные в...

84
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
15.04.2014, 22:12  [ТС] 41
Author24 — интернет-сервис помощи студентам
все, таки я не могу успокоиться)) почему-то у меня при 3-х потоках программа выполняется около 300с, а при одном потоке всего 30с, что за фигня я не могу понять %)
0
Заблокирован
15.04.2014, 22:42 42
Цитата Сообщение от NEvOl Посмотреть сообщение
все, таки я не могу успокоиться)) почему-то у меня при 3-х потоках программа выполняется около 300с, а при одном потоке всего 30с, что за фигня я не могу понять %)
просто интересно, а какой у тебя CPU?
на самом деле, тут всё совсем не просто, есть такие вещи, как эксклюзивные процессорные такты, memory caolescing и многое другое. Для оптимального параллелизма код должен быть заточен под это.

Даю тебе следующее задание. Напиши не из своего кода, а просто отдельные маленький пример с сортировкой, чтоб этот код был в строчек 10...15, чтоб удобно его изучать было и сам проверь на нём и сюда выложи. Посмотрим. Например, три вектора, которые надо отсортировать.
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
16.04.2014, 10:53  [ТС] 43
так ну вот я написал в консольке:
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <iostream>
#include <D3DX11.h>
#include <vector>
#include <xnamath.h>
#include <thread>
 
using namespace std;
 
struct photon 
{
    XMFLOAT4 pos;
};
 
void qSortX(photon *p, int e);
void qSortY(photon *p, int e);
void qSortZ(photon *p, int e);
 
int _tmain(int argc, _TCHAR* argv[])
{
    int num = 250000;
    bool thr(0);
    photon *p = new photon[num];
    photon *x = new photon[num];
    photon *y = new photon[num];
    photon *z = new photon[num];
    for(int i = 0; i < num; i++)
    {
        p[i].pos.x = rand()%20-10;
        p[i].pos.y = rand()%20-10;
        p[i].pos.z = rand()%20-10;
    }
    DWORD start = GetTickCount();
    std::cout<<"num:"<<num;
    cout<<endl<<"enter type threed";
    cin>>thr;
    std::cout<<"\nStart at :"<<start;
    if(thr)
    {
        cout<<endl<<"threed - 3";
        std::thread h1(qSortX, x, num-1);
        std::thread h2(qSortX, x, num-1);
        std::thread h3(qSortX, x, num-1);
        h1.join();
        h2.join();
        h3.join();
    }
    else
    {
        cout<<endl<<"threed - 1";
        qSortX(x, num-1);
        qSortY(y, num-1);
        qSortZ(z, num-1);
    }
    DWORD end = GetTickCount();
    std::cout<<"\nend at:"<<end;
    std::cout<<"\ntime:"<<(end-start)/1000.f<<" s";
    char a;
    std::cin>>a;
    _tmain(argc, argv);
    return 0;
}
 
 
void qSortZ(photon *p, int e)
{
    int b = 0;
    vector<XMFLOAT2> stack;
    float ind = p[e].pos.z;
    int sI = e;
    int j = e-1;
    bool s(0);
 
    do
    {
        for(int i = b; i < e; i++)
        {
            j = e-1;
            ind = p[e].pos.z;
            if(p[i].pos.z >= ind)
            {
                while(p[j].pos.z >= ind && j > i)
                {
                    j--;
                }
                if(j > i)
                {
                    photon a = p[i];
                    p[i] = p[j];
                    p[j] = a;
                    sI = i+1;
                }
                else
                    break;
            }
        }
        for(int i = b; i <= e; i++)
        {
            if(p[i].pos.z >= ind)
            {
                photon a = p[i];
                p[i] = p[e];
                p[e] = a;
                sI = i;
                if(e - i > 1)
                    stack.push_back(XMFLOAT2(sI+1, e));
                break;
            }
        }
 
        if(sI-b <= 1 && stack.size() > 0)
        {
            b = stack[stack.size()-1].x;
            e = stack[stack.size()-1].y;
            stack.pop_back();
            continue;
        }
 
        e = sI - 1;
 
 
    }while(e-b >= 1 || stack.size() != 0);
}
 
void qSortY(photon *p, int e)
{
    int b = 0;
    vector<XMFLOAT2> stack;
    float ind = p[e].pos.y;
    int sI = e;
    int j = e-1;
    bool s(0);
 
    do
    {
        for(int i = b; i < e; i++)
        {
            j = e-1;
            ind = p[e].pos.y;
            if(p[i].pos.y >= ind)
            {
                while(p[j].pos.y >= ind && j > i)
                {
                    j--;
                }
                if(j > i)
                {
                    photon a = p[i];
                    p[i] = p[j];
                    p[j] = a;
                    sI = i+1;
                }
                else
                    break;
            }
        }
        for(int i = b; i <= e; i++)
        {
            if(p[i].pos.y >= ind)
            {
                photon a = p[i];
                p[i] = p[e];
                p[e] = a;
                sI = i;
                if(e - i > 1)
                    stack.push_back(XMFLOAT2(sI+1, e));
                break;
            }
        }
 
        if(sI-b <= 1 && stack.size() > 0)
        {
            b = stack[stack.size()-1].x;
            e = stack[stack.size()-1].y;
            stack.pop_back();
            continue;
        }
 
        e = sI - 1;
 
 
    }while(e-b >= 1 || stack.size() != 0);
}
 
 
void qSortX(photon *p, int e)
{
    int b = 0;
    vector<XMFLOAT2> stack;
    float ind = p[e].pos.x;
    int sI = e;
    int j = e-1;
    bool s(0);
 
    do
    {
        for(int i = b; i < e; i++)
        {
            j = e-1;
            ind = p[e].pos.x;
            if(p[i].pos.x >= ind)
            {
                while(p[j].pos.x >= ind && j > i)
                {
                    j--;
                }
                if(j > i)
                {
                    photon a = p[i];
                    p[i] = p[j];
                    p[j] = a;
                    sI = i+1;
                }
                else
                    break;
            }
        }
        for(int i = b; i <= e; i++)
        {
            if(p[i].pos.x >= ind)
            {
                photon a = p[i];
                p[i] = p[e];
                p[e] = a;
                sI = i;
                if(e - i > 1)
                    stack.push_back(XMFLOAT2(sI+1, e));
                break;
            }
        }
 
        if(sI-b <= 1 && stack.size() > 0)
        {
            b = stack[stack.size()-1].x;
            e = stack[stack.size()-1].y;
            stack.pop_back();
            continue;
        }
 
        e = sI - 1;
 
 
    }while(e-b >= 1 || stack.size() != 0);
}
функции сортировки использовал теже что и в прошлый раз, тут все работает адекватно, т.е. при сортировки 1-им потоком требуется около 130 с при сортировки 3-мя потоками требуется около 50 с, следовательно проблема в функции CreateTree, буду копать ее.
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
18.04.2014, 11:02  [ТС] 44
хм... с сортировкой я вроде разобрался, действительно работает быстрее, но вот меня беспокоит функция создания kd дерева, в ней так же происходит сортировка массивов, если я использую 3 потока для сортировки то построение выполняется в разы медленнее чем когда одним потоком сортирую, код далек от совершенства, но рабочий, подскажите пожалуйста почему так ? при проверке показало что если использовать 3 потока для сортировки то времени уходит около 1000 секунд, а при использовании одного потока для сортировки всего 20 с, это у меня вообще в голове не укладывается как так ?
переделал немного код:
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
void nodeKdTree::CreateTree(photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch, bool thr)
{
    if(num == 1)
    {
        this->pht = p[0];
        newP[iStart].pos = p[0].pos;
        newP[iStart].energy = p[0].energy;
        newP[iStart].l = -1;
        newP[iStart].r = -1;
        if(iBranch == 1)
            newP[rootIndex].r = iStart;
        else
            newP[rootIndex].l = iStart;
        this->left = NULL;
        this->right = NULL;
        this->key = 0;
        this->lNum = 0;
        this->rNum = 0;
        this->numInArr = 0;
        return;
    }
    photon *x = new photon[num];
    photon *y = new photon[num];
    photon *z = new photon[num];
 
    std::memcpy(x, p,sizeof(photon)*num);
    std::memcpy(y, p,sizeof(photon)*num);
    std::memcpy(z, p,sizeof(photon)*num);
 
    if(thr)
    {
        std::thread th1(qSortX, x, num-1);
        std::thread th2(qSortY, y, num-1);
        std::thread th3(qSortZ, z, num-1);
 
        th1.join();
        th2.join();
        th3.join();
    }
    else
    {
        qSortX(x, num-1);
        qSortY(y, num-1);
        qSortZ(z, num-1);
    }
 
    int dx = abs(x[0].pos.x - x[num-1].pos.x);
    int dy = abs(y[0].pos.y - y[num-1].pos.y);
    int dz = abs(z[0].pos.z - z[num-1].pos.z);
    this->left = new nodeKdTree();
    this->right = new nodeKdTree();
 
 
    int newIndex(-1);
    if((dx > dy && dx > dz) || (dx == dy && dx > dz) || (dx == dz && dx > dy))
    {
        int m = num/2;
        this->numInArr = m;
        int lnum;
        int rnum;
        this->pht = x[m];
        newIndex = iStart+m;
        newP[newIndex].pos = x[m].pos;
        newP[newIndex].energy = x[m].energy;
        if(iBranch == 1)
            newP[rootIndex].r = newIndex;
        if(iBranch == -1)
            newP[rootIndex].l = newIndex;
        if(rootIndex == -1)
        {
            newP[newIndex].l = -1;
            newP[newIndex].r = -1;
        }
        newP[newIndex].k = 1;
        this->key = 1;
        lnum = m;
        photon *lx = new photon[lnum];
        std::memcpy(lx, x, sizeof(photon)*lnum);
        photon *rx;
        if(num%2)
        {
            rnum = m;
            rx = new photon[rnum];
            std::memcpy(rx, x+m+1, sizeof(photon)*rnum);
        }
        else
        {
            rnum = num-m-1;
            if(rnum > 0)
            {
                rx = new photon[rnum];
                std::memcpy(rx, x+m+1, sizeof(photon)*rnum);
            }
        }
        this->left->CreateTree(lx, newP, lnum, iStart, newIndex, -1, thr);
        delete []lx;
        this->lNum = lnum;
        this->rNum = rnum;
        if(rnum > 0)
        {
            this->right->CreateTree(rx, newP, rnum, newIndex+1, newIndex, 1, thr);
            delete []rx;
        }
    }
    else
        if((dy > dx && dy > dz) || (dy == dz && dy > dx))
        {
            int m = num/2;
            this->numInArr = m;
            int lnum;
            int rnum;
            this->pht = y[m];
            newIndex = iStart+m;
            newP[newIndex].pos = y[m].pos;
            newP[newIndex].energy = y[m].energy;
            if(iBranch == 1)
                newP[rootIndex].r = newIndex;
            if(iBranch == -1)
                newP[rootIndex].l = newIndex;
            if(rootIndex == -1)
            {
                newP[newIndex].l = -1;
                newP[newIndex].r = -1;
            }
            newP[newIndex].k = 2;
            this->key = 2;
            lnum = m;
            photon *ly = new photon[lnum];
            std::memcpy(ly, y, sizeof(photon)*lnum);
            photon *ry;
            if(num%2)
            {
                rnum = m;
                ry = new photon[rnum];
                std::memcpy(ry, y+m+1, sizeof(photon)*rnum);
            }
            else
            {
                rnum = num-m-1;
                if(rnum > 0)
                {
                    ry = new photon[rnum];
                    std::memcpy(ry, y+m+1, sizeof(photon)*rnum);
                }
            }
            this->left->CreateTree(ly, newP, lnum, iStart, newIndex, -1, thr);
            delete []ly;
            this->lNum = lnum;
            this->rNum = rnum;
            if(rnum > 0)
            {
                this->right->CreateTree(ry, newP, rnum, newIndex+1, newIndex, 1, thr);
                delete []ry;
            }
        }
        else
            {
                int m = num/2;
                this->numInArr = m;
                int lnum;
                int rnum;
                this->pht = z[m];
                newIndex = iStart+m;
                newP[newIndex].pos = z[m].pos;
                newP[newIndex].energy = z[m].energy;
                if(iBranch == 1)
                    newP[rootIndex].r = newIndex;
                if(iBranch == -1)
                    newP[rootIndex].l = newIndex;
                if(rootIndex == -1)
                {
                    newP[newIndex].l = -1;
                    newP[newIndex].r = -1;
                }
                newP[newIndex].k = 3;
                this->key = 3;
                lnum = m;
                photon *lz = new photon[lnum];
                std::memcpy(lz, z, sizeof(photon)*lnum);
                photon *rz;
                if(num%2)
                {
                        rnum = m;
                        rz = new photon[rnum];
                        std::memcpy(rz, z+m+1, sizeof(photon)*rnum);
                }
                else
                {
                    rnum = num-m-1;
                    if(rnum > 0)
                    {
                        rz = new photon[rnum];
                        std::memcpy(rz, z+m+1, sizeof(photon)*rnum);
                    }
                }
                this->left->CreateTree(lz, newP, lnum, iStart, newIndex, -1, thr);
                delete []lz;
                this->lNum = lnum;
                this->rNum = rnum;
                if(rnum > 0)
                {
                    this->right->CreateTree(rz, newP,  rnum, newIndex+1, newIndex, 1, thr);
                    delete []rz;
                }
            }
    return;
}
 
void qSortZ(photon *p, int e)
{
    std::qsort(p, e+1, sizeof(photon), funcZ);
}
 
void qSortY(photon *p, int e)
{
    std::qsort(p, e+1, sizeof(photon), funcY);
}
 
 
void qSortX(photon *p, int e)
{
    std::qsort(p, e+1, sizeof(photon), funcX);
}
 
int funcX(const void* a, const void* b)
{
    if((*(photon*)a).pos.x > (*(photon*)b).pos.x)
        return 1;
    if((*(photon*)a).pos.x < (*(photon*)b).pos.x)
        return -1;
    return 0;
}
 
int funcY(const void* a, const void* b)
{
    if((*(photon*)a).pos.y > (*(photon*)b).pos.y)
        return 1;
    if((*(photon*)a).pos.y < (*(photon*)b).pos.y)
        return -1;
    return 0;
}
 
int funcZ(const void* a, const void* b)
{
    if((*(photon*)a).pos.z > (*(photon*)b).pos.z)
        return 1;
    if((*(photon*)a).pos.z < (*(photon*)b).pos.z)
        return -1;
    return 0;
}
пояснения:
в функцию передается исходный массив с координатами точек в 3D(p), новый массив который постепенно заполняется и представляет само kd дерево(newP), количество элементов в переданном массиве p (num), индекс начала переданного подмассива в исходном массиве p (iStart), индекс узла дерева чьи ветви рассчитываются в текущий момент в массиве newp (rootIndex), индекс правой - 1 и левой - -1 ветви (iBranch) и последним параметром является метод сортировки массивов 3-мя потоками или одним (thr). Суть функции заключается в том что сортируются координаты точек по 3-м осям (x, y, z) затем находится по какой из осей максимальное расстояние между крайними точками, массив разбивается на 2 части, центральный элемент сохраняется после этого остальные части массива (правая и левая) отправляются рекурсивно в эту же функцию и так пока весь массив не переберется. помогите пожалуйста разобраться.
0
Заблокирован
18.04.2014, 11:46 45
Ты в VisualStudio прогаешь? Запускай из меню ANALIZE->StartPerformenceAnalize и смотри, какая часть кода у тебя больше всего времени занимает... И вообще учись профайлерами пользоваться. Или выкладывай сюда архив с проектом и комментом - "ТУТ У МЕНЯ КОСЯК!!!! ЕСЛИ РАСКОМЕНТИТЬ ЭТИ СТРОЧКИ, ТО БУДЕТ НА МНОГО МЕДЛЕННЕЕ!"
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
18.04.2014, 11:55  [ТС] 46
Цитата Сообщение от newbie666 Посмотреть сообщение
профайлерами
это что за зверь ?
0
Заблокирован
18.04.2014, 12:19 47
Цитата Сообщение от NEvOl Посмотреть сообщение
это что за зверь ?
ну в гугЛь вбей С++ профайлеры
В основном это штуковины для анализа производительности программ.
В VisualStudio есть встроенный -
Цитата Сообщение от newbie666 Посмотреть сообщение
Запускай из меню ANALIZE->StartPerformenceAnalize
1
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
18.04.2014, 23:32  [ТС] 48
странно как-то этот анализ работает, запускаю его программа секунд 10-15 поработает, до конца не дойдет и вырубается он.

Добавлено через 26 минут
что еще интересно это то что, анализ так себя ведет именно тогда когда я выбираю сортировку с 3-мя потоками (когда очень долго выполняется ~1000 с) а когда выбираю сортировку 1-им потоком то все норально, жесть какая-то непонятная

Добавлено через 4 часа 43 минуты
newbie666, объясните пожалуйста как получить указатель на метода класса ? что бы указать для потоку ее в качестве функции потока.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 10:54 49
Цитата Сообщение от NEvOl Посмотреть сообщение
что бы указать для потоку ее в качестве функции потока.
Передать указатель на метод в поток не получится, но можно передать в поток функтор, в котором будет вызываться данный метод.
1
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 11: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
class nodeKdTree
{
    public:
    nodeKdTree *right;
    nodeKdTree *left;
    int rNum;
    int lNum;
    int numInArr;
    photon pht;
    int key;//1 - x 2 - y 3 - z
    void CreateTree(photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch);
    nodeKdTree GetThisPointer();
};
 
void CreateTreeWrap(nodeKdTree &node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
{
    node.CreateTree(p, newP, num, iStart, rootIndex, iBranch);
}
 
nodeKdTree nodeKdTree::GetThisPointer()
{
    return *this;
}
пытаюсь вызывать так:
C++
1
std::thread th1(CreateTreeWrap, this->GetThisPointer(), lz, newP, lnum, iStart, newIndex, -1);
но ошибку кидает:
1 IntelliSense: no instance of constructor "std::thread::thread" matches the argument list
argument types are: (void (nodeKdTree &node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch), nodeKdTree, photon *, nodePhoton *, int, int, int, int) c:\filtering1\Filtering\kdTree.h 229
(функция nodeKdTree::CreateTree) должна вызываться рекурсивно.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 11:11 51
Цитата Сообщение от NEvOl Посмотреть сообщение
что-то типа обвертки ?
"Что-то типа" функтора.
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 11:56  [ТС] 52
alsav22, на сколько я понял в функторах перегружается оператор (), я реализовал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class nodeKdTree
{
    public:
    nodeKdTree *right;
    nodeKdTree *left;
    int rNum;
    int lNum;
    int numInArr;
    photon pht;
    int key;//1 - x 2 - y 3 - z
    void CreateTree(photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch);
    void operator() (photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
    {
        this->CreateTree(p, newP, num, iStart, rootIndex, iBranch);
    }
    nodeKdTree GetThisNode();
};
 
void CreateTreeWrap(nodeKdTree node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
{
    node(p, newP, num, iStart, rootIndex, iBranch);
}
так ?

Добавлено через 8 минут
использование шаблонов ведь не обязательно ?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 12:03 53
Цитата Сообщение от NEvOl Посмотреть сообщение
так ?
Так.
1
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 12:06  [ТС] 54
alsav22, но при попытке использовать
C++
1
void CreateTreeWrap(nodeKdTree node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
в качестве поточной функции, т.е. так:
C++
1
std::thread th1(CreateTreeWrap, left, lz, newP, lnum, iStart, newIndex, -1);
то ывбрасывает ошибку:
1 IntelliSense: no instance of constructor "std::thread::thread" matches the argument list
argument types are: (void (nodeKdTree node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch), nodeKdTree *, photon *, nodePhoton *, int, int, int, int) c:\filtering1\Filtering\kdTree.h 233
я не пойму почему.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 12:20 55
Цитата Сообщение от NEvOl Посмотреть сообщение
т.е. так:
То есть, не так. Я же написал, что можно передать в поток:
Цитата Сообщение от alsav22 Посмотреть сообщение
но можно передать в поток функтор,
Функтор - это объект класса, в котором и т.д.

Добавлено через 1 минуту
Создавайте объект nodeKdTree и передавайте его в поток вместе с параметрами для nodeKdTree::operator().

Добавлено через 5 минут
В потоке будет вызываться то, что вызывается в nodeKdTree::operator().
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 12:36  [ТС] 56
alsav22, честно говоря я плохо понимаю пока функторы, я сделал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class nodeKdTree
{
    public:
    nodeKdTree *right;
    nodeKdTree *left;
    int rNum;
    int lNum;
    int numInArr;
    photon pht;
    int key;//1 - x 2 - y 3 - z
    void CreateTree(photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch);
    void operator() (nodeKdTree node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
    {
        node.CreateTree(p, newP, num, iStart, rootIndex, iBranch);
    }
};
и мне нужно создать объект, и передать его в поток со всеми параметрами для operator():
C++
1
2
nodeKdTree a;
std::thread th1(a, this->left, lz, newP, lnum, iStart, newIndex, -1);
но что-то я не так делаю.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 12:43 57
Цитата Сообщение от NEvOl Посмотреть сообщение
nodeKdTree a;
std::thread th1(a, this->left, lz, newP, lnum, iStart, newIndex, -1);
Это где делается? this здесь откуда?

Добавлено через 1 минуту
Цитата Сообщение от NEvOl Посмотреть сообщение
но что-то я не так делаю.
Не компилируется?
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 12:46  [ТС] 58
Цитата Сообщение от alsav22 Посмотреть сообщение
Это где делается?
это делается внутри функции nodeKdTree::CreateTree()
у объекта nodeKdTree имеется объект left (nodeKdTree) для которого нужно вызвать функцию CreateTree().

Добавлено через 52 секунды
вот что говорит:
1 IntelliSense: no instance of constructor "std::thread::thread" matches the argument list
argument types are: (nodeKdTree (), nodeKdTree *, photon *, nodePhoton *, int, int, int, int) c:\filtering1\Filtering\kdTree.h 246
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.04.2014, 12:48 59
И не нужно, в operator(), передавать nodeKdTree node, метод класса и так может вызвать другой метод класса.
0
20 / 19 / 1
Регистрация: 13.08.2012
Сообщений: 779
19.04.2014, 12:58  [ТС] 60
alsav22, это я понимаю, суть функтора это объект который фыполняет какие-то действия ?
т.е. в моем случае он должен вызывать метод объекта, я могу написать так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class functor
{
    functor()
    {
 
    }
    ~functor()
    {
 
    }
    void operator() (nodeKdTree node, photon *p, nodePhoton *newP, int num, int iStart, int rootIndex, int iBranch)
    {
        node.CreateTree(p, newP, num, iStart, rootIndex, iBranch);
    }
};
при этом объект класса functor это будет функтор, который можно передать в поток со всеми параметрами? например так:
C++
1
2
functor a
std::thread th1(a, this->left, lz, newP, lnum, iStart, newIndex, -1);
0
19.04.2014, 12:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.04.2014, 12:58
Помогаю со студенческими работами здесь

Многопоточность: вывести на экран символ, который встречается наибольшее количество раз в каждом из массивов
У меня есть такая задачка: Есть 3 массивы 1 содержит 2 миллиона символов 2 содержит 1000000...

Ошибка при сортировке
При сортировке массива вылетает причем именно на последнем числе сортирую так : for (int...

Ошибка при сортировке Шелла
Сортирую массив, вношу в него 46 элементов случайных значений в диапазоне от 1 до 26, после...

Ошибка при сортировке пузырьком
Видимо выход за предел массива, не пойму где ошибка #include &lt;iostream&gt; #include &lt;ctime&gt;...


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

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