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

Производительность CPU, КЕШ, многопоточность - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Проблемы с удалением связанного списка(С++) http://www.cyberforum.ru/cpp-beginners/thread647138.html
Здравствуйте! Передо мной стоит следующая задача: необходимо создать список, вывести его на экран и удалить. Программу необходимо запускать несколько раз, вот в этом и возник ступор. Дело в том, что программа создает список, выводит его на экран и удаляет первый раз вроде исправно, но второй раз программа выдает ошибку на выводе списка(как я понял, либо программа не правильно удаляет связанный...
C++ Логические операторы в выражениях Здравствуйте, в одном из тестов для новичков наткнулся на вопрос: каков результат работы следующего кода: int d = 5; bool b = true, c; c = ( !b || (d>3) ); Я думал будет ошибка компиляции, однако ошибся. Вот как понять третью строку? Ведь в ней говорится - "c равно false или true". Как же компилятор понимает какое значение присваивать переменной с, если у него больше нет никаких условий?... http://www.cyberforum.ru/cpp-beginners/thread647118.html
Определить количество и сумму членов последовательности C++
Даны натуральное n и целые числа a(1), a(2),...,a(n). Определить количество и сумму членов последовательности a(i), которые делятся на 5 и не делятся на 7. P.S. Необходимо написать без использования массива, помогите, пожалуйста.
Матрицы C++
Заполнить двумерный массив размером 7х7 след. образом: (см.картинку). Помогите да пацаны
C++ Не получается сделать программу добавив методы http://www.cyberforum.ru/cpp-beginners/thread647101.html
Здравствуйте! Я написал программу для расчётов, сравнения и вывода на экран двух цилиндров. Проблема заключается в том, что не могу расписать через методы (вывод на экран, расчёты, сравнения и др. операции). Не могли бы вы мне помочь? Буду очень признателен. Ссылка на прогу ниже.
C++ Error C3861: 'convert_close': identifier not found //ошибка Ребята вы пожалуйста не обращайте внимание на код, обратите только внимание на на одну ошибку. #include "stdafx.h" #include <iostream> #include <iomanip> #include <fstream> using namespace std; подробнее

Показать сообщение отдельно
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
06.09.2012, 10:26     Производительность CPU, КЕШ, многопоточность
Код много раз менялся, что-то добавлял, что-то удалял, поэтому выглядет как каша. Я даже уже не помню, рабочая ли это версия. Но при большом желании можно разобраться
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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <algorithm>
#include <cerrno>
#include <cstring>
#include <getopt.h>
 
#define L1_CACHE_BYTES  (1 << 6)
#define PREFETCH_STRIDE (4*L1_CACHE_BYTES)
 
#define _3D_INDEX(_x,_y,_z)    (_z) * global_args::y * global_args::x + (_y) * global_args::x + (_x)
 
#define LEFT_VAL(_x,_y,_z)    ((_x) > 0 ? matrix[_3D_INDEX((_x - 1),(_y),(_z))].array[p] : 0)
#define RIGHT_VAL(_x,_y,_z)   ((_x) < global_args::x - 1 ? matrix[_3D_INDEX((_x + 1),(_y),(_z))].array[p] : 0)
#define FRONT_VAL(_x,_y,_z)   ((_y) < global_args::y - 1 ? matrix[_3D_INDEX((_x),(_y + 1),(_z))].array[p] : 0)
#define BACK_VAL(_x,_y,_z)    ((_y) > 0 ? matrix[_3D_INDEX((_x),(_y - 1),(_z))].array[p] : 0)
#define UP_VAL(_x,_y,_z)      ((_z) < global_args::z - 1 ? matrix[_3D_INDEX((_x),(_y),(_z + 1))].array[p] : 0)
#define DOWN_VAL(_x,_y,_z)    ((_z) > 0 ? matrix[_3D_INDEX((_x),(_y),(_z - 1))].array[p] : 0)
 
#define LEFT_ADDR(_x,_y,_z)   ((_x) > 0 ? &(matrix[_3D_INDEX((_x - 1),(_y),(_z))]) : NULL)
#define RIGHT_ADDR(_x,_y,_z)  ((_x) < global_args::x - 1 ? &(matrix[_3D_INDEX((_x + 1),(_y),(_z))]) : NULL)
#define FRONT_ADDR(_x,_y,_z)  ((_y) < global_args::y - 1 ? &(matrix[_3D_INDEX((_x),(_y + 1),(_z))]) : NULL)
#define BACK_ADDR(_x,_y,_z)   ((_y) > 0 ? &(matrix[_3D_INDEX((_x),(_y - 1),(_z))]) : NULL)
#define UP_ADDR(_x,_y,_z)     ((_z) < global_args::z - 1 ? &(matrix[_3D_INDEX((_x),(_y),(_z + 1))]) : NULL)
#define DOWN_ADDR(_x,_y,_z)   ((_z) > 0 ? &(matrix[_3D_INDEX((_x),(_y),(_z - 1))]) : NULL)
 
 
struct node {
    static const size_t size = 100;
    int array[size];
};//__attribute__((aligned(0x4)));
 
struct global_args {
    static size_t block_size;
    static size_t foffset;
    static size_t byte_to_pref;
    static size_t threads;
 
    static const size_t x = 225, y = 225, z = 20, arr_size = x * y * z; //1 012 500
};
 
size_t global_args::block_size = -1;
size_t global_args::foffset = -1;
size_t global_args::byte_to_pref = -1;
size_t global_args::threads = -1;
 
struct args_for_thread {
    size_t beg_x, beg_y, beg_z;
    size_t end_x, end_y, end_z;
    static node *ptr;
    size_t length;
};
 
node *args_for_thread::ptr = NULL;
 
void prefetch_district_point(node *matrix, size_t x, size_t y, size_t z)
{
    node *addrs[] = {LEFT_ADDR(x,y,z), RIGHT_ADDR(x,y,z),  UP_ADDR(x,y,z), DOWN_ADDR(x,y,z)};
 
    for(size_t i = 0; i < sizeof(addrs) / sizeof(*addrs); i++) {
        if (addrs[i]) {
            for(size_t bytes = 0; bytes < 400; bytes += global_args::byte_to_pref) {
               __builtin_prefetch(&(addrs[i] -> array[bytes / sizeof(int)]), 0, 2);
            }
        }
    }
}
 
void prefetch_block_points(node *matrix, size_t _x, size_t _y, size_t _z)
{
    int point_count = global_args::block_size;
 
    for(size_t z = _z; z < global_args::z; z++) {
        for(size_t y = _y; y < global_args::y; y++) {
            for(size_t x = _x; x < global_args::x; x++) {
                prefetch_district_point(matrix, x, y, z);
 
                --point_count;
                if (!point_count) {
                    return;
                }
            }
        }
    }
}
 
int calc_point(node *matrix, size_t x, size_t y, size_t z)
{
    int result = 0;
 
    for(size_t p = 0; p < node::size; p++) {
        matrix[_3D_INDEX(x,y,z)].array[p] = (LEFT_VAL(x,y,z) +
                                             RIGHT_VAL(x,y,z) +
                                             FRONT_VAL(x,y,z) +
                                             BACK_VAL(x,y,z) +
                                             UP_VAL(x,y,z) +
                                             DOWN_VAL(x,y,z)
                                             ) / 6;
 
        result += matrix[_3D_INDEX(x,y,z)].array[p] ;
    }
    return result;
}
 
unsigned int calculated(args_for_thread *arg)
{
    node *matrix = args_for_thread::ptr;
    unsigned int result = 0;
    int point_count = 0;
 
    for(int cnt = 0; cnt < 2; cnt++) {
        for(size_t z = arg -> beg_z; z < global_args::z; z++) {
            for(size_t y = arg -> beg_y; y < global_args::y; y++) {
                for(size_t x = arg -> beg_x; x < global_args::x; x++) {
                    if (point_count == 0) {
                        int diff = global_args::foffset;
                        int xy = global_args::x * global_args::y;
                        size_t zz = diff / xy;
                        size_t yy = (diff % xy) / global_args::x;
                        size_t xx =  (diff % xy) % global_args::x;
 
                        if (xx + x >= global_args::x) {
                            ++yy;
                            xx = xx + x - global_args::x;
                        } else {
                            xx += x;
                        }
                        if (yy + y >= global_args::y) {
                            ++zz;
                            yy = yy + y - global_args::y;
                        } else {
                            yy += y;
                        }
                        if (zz + z < global_args::z) {
                            zz += z;
                            prefetch_block_points(matrix, xx, yy, zz);
                        }
                    }
 
                    result += calc_point(matrix, x, y, z);
 
                    -- arg -> length;
                    if(! arg -> length) {
                        return result;
                    }
 
                    ++point_count;
                    if (point_count == global_args::block_size) {
                        point_count = 0;
                    }
                }
            }
        }
    }
 
    return result;
}
 
 
int main(int argc, char* argv[])
{
    const struct option opts[] = {
                                    {"bs", required_argument, NULL, 's'}, //size of block
                                    {"fof", required_argument, NULL, 'f'}, // offset to start prefetch
                                    {"btp", required_argument, NULL, 'b'}, // step to prefetch (in bytes)
                                    {"threads", required_argument, NULL, 't'}, //number of threads
                                    {NULL, 0, NULL, 0}
                                };
    const char *opt_string = "b:f:s:t:";
    int opt_index = 0;
 
    int opt;
    while((opt = getopt_long(argc, argv, opt_string, opts, &opt_index)) != -1) {
        switch(opt) {
 
        case 'f':
            global_args::foffset = atoi(optarg);
            break;
 
        case 'b':
            global_args::byte_to_pref = atoi(optarg);
            break;
 
        case 's':
            global_args::block_size = atoi(optarg);
            break;
 
        case 't':
            global_args::threads = atoi(optarg);
            break;
        }
    }
 
 
    /*global_args::block_size = 512;
    global_args::foffset = 256;
    global_args::byte_to_pref = 400;
    global_args::threads = 25;*/
 
    if (global_args::block_size == -1 || global_args::foffset == -1 ||
        global_args::byte_to_pref == -1 || global_args::threads == -1) {
        std::cout << "Arguments is required!" << std::endl;
        return 1;
    }
 
//***********************************************************************************
    node *matrix;
 
    try {
        matrix = new node[global_args::arr_size];
    } catch (std::exception &e) {
        std::cout << "Exception: " << e.what() << std::endl;
        return 1;
    }
 
    args_for_thread::ptr = matrix;
 
    for(size_t i = 0; i < global_args::z; i++) {
        for(size_t j = 0; j < global_args::y; j++) {
            for(size_t k = 0; k < global_args::x; k++) {
                for(size_t p = 0; p < node::size; p++) {
                    matrix[_3D_INDEX(k,j,i)].array[p] = i * j * k;
                }
            }
        }
    }
 
    pthread_t *threads = new pthread_t[global_args::threads];
    args_for_thread *th_args = new args_for_thread[global_args::threads];
    size_t length_for_each = global_args::arr_size / global_args::threads;
 
    for(size_t i = 0; i < global_args::threads; i++) {
        size_t beg_x, beg_y, beg_z, end_x, end_y, end_z;
        const size_t xy = global_args::x * global_args::y;
 
        beg_z = (i * length_for_each) / xy;
        beg_y = ((i * length_for_each) % xy) / global_args::x;
        beg_x = ((i * length_for_each) % xy) % global_args::x;
 
        if (i + 1 != global_args::threads) {
            end_z = ((i + 1) * length_for_each) / xy;
            end_y = (((i + 1) * length_for_each) % xy) / global_args::x;
            end_x = (((i + 1) * length_for_each) % xy) % global_args::x;
            th_args[i].length = length_for_each;
        } else {
            end_z = global_args::z;
            end_y = global_args::y;
            end_x = global_args::x;
            th_args[i].length = global_args::arr_size - i * length_for_each;
        }
 
        th_args[i].beg_x = beg_x;
        th_args[i].beg_y = beg_y;
        th_args[i].beg_z = beg_z;
        th_args[i].end_x = end_x;
        th_args[i].end_y = end_y;
        th_args[i].end_z = end_z;
    }
 
    timespec time_start, time_end;
    long long int result = 0;
 
    std::cout << "Start calculation..." << std::endl;
 
    clock_gettime(CLOCK_REALTIME, &time_start);
 
    for(size_t i = 0; i < global_args::threads; i++) {
        int res = pthread_create(&threads[i], NULL, reinterpret_cast<void*(*)(void*)>(calculated), &th_args[i]);
        if (res) {
            std::cout << "Error: " << strerror(res) << std::endl;
            return 1;
        }
    }
 
    for(size_t i = 0; i < global_args::threads; i++) {
        void* calc_result = 0;
        int res = pthread_join(threads[i], &calc_result);
        if (res) {
            std::cout << "Error join " << i << " thread: " << strerror(res) << std::endl;
        }
 
        result += reinterpret_cast<unsigned int>(calc_result);
    }
 
    clock_gettime(CLOCK_REALTIME, &time_end);
 
    int result_sec = time_end.tv_sec - time_start.tv_sec;
    int result_nsec;
    const int nanoseconds = 1E9, digits = 9;
 
    if(time_end.tv_nsec > time_start.tv_nsec) {
        result_nsec = time_end.tv_nsec - time_start.tv_nsec;
    } else {
        if(result_sec > 0) {
            --result_sec;
        }
        result_nsec = nanoseconds - time_start.tv_nsec + time_end.tv_nsec;
    }
 
    std::cout << "Time calculation: " << result_sec << "." << std::setw(digits) << std::setfill('0') << result_nsec << std::endl;
 
    std::cout << "Result: = " << result << std::endl;
 
    delete [] matrix;
 
    return 0;
}
Тут моделируется т.н. stencil computation - это когда в кубе для вычисления значения в какой-то точке необходимо обратиться к всем ее соседям. В качестве производимой операции выбрано простейшее сложение.
P.S. комплируется только под Linux.
 
Текущее время: 04:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru