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 <tbb/tbb.h> // Включает в себя все заголовочные файлы библиотеки
#include <stdio.h>
#include <cstdlib>
#include <tbb/blocked_range.h>
#include <tbb/parallel_reduce.h>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>
#include <tbb/tick_count.h>
//using std::cout;
//using std::cin;
//using std::endl;
//using std::cin;
using namespace std;
// Скалярное умножение векторов
double VectorsMultiplication(double *v1, double *v2, double *rez, int size)
{
for(int i = 0; i < size; i++)
for(int j = 0; j < size; j++)
{
rez[i+j] = 0;
for(int k = 0; k < size; k++)
rez[i+j] += (v1[i+k] * v1[k*size+j]);
}
// return rez;
}
// Функтор
class ScalarMultiplicator
{
private:
double *a; // Вектор 1
double *b; // Вектор 2
double c; // Результат
public:
// Конструктор
/*explicit*/ ScalarMultiplicator(double *ta, double *tb) : a(ta), b(tb), c(0) {}
// Конструктор копирования (расщепления)
ScalarMultiplicator(const ScalarMultiplicator &m, tbb::split) : a(m.a), b(m.b), c(0) {} //Параметр split (служебный класс без полей и методов) предназначен для того, чтобы отличить конструктор копирования от конструктора расщепления
// Выполняет вычисления
void operator()(const tbb::blocked_range<int> &r)
{
int begin = r.begin();
int end = r.end();
c += VectorsMultiplication(&(a[begin]), &(b[begin]), (end - begin)); // Ошибка!
/* for (int i = begin; i < (end - begin); i++)
c += a[i] * b[i];*/
}
// Выполняет редукцию
void join(const ScalarMultiplicator & multiplicator)
{
c += multiplicator.c;
}
// Возвращает окончательный результат
double Res()
{
return c;
}
};
void product_posled(double *vec_1, double *vec_2); // Для проверки: последовательное вычисление скалярного произведения
long size_vec; // Размер вектора
int main()
{
cout << "Please, input size of vector's: ";
cin >> size_vec;
cout << endl;
cout << "First vector:" << endl;
double *ptr_vec_1 = new double[size_vec * size_vec]; // Создание 1-го вектора
for (int count = 0; count < size_vec * size_vec; count++)
{
ptr_vec_1[count] = (rand() % 10 + 1) / double((rand() % 10 + 1)); // Заполнение вектора 1 случайными числами с масштабированием от 1 до 10
cout << ptr_vec_1[count] << " ";
}
cout << endl;
cout << endl;
cout << "Second vector:" << endl;
double *ptr_vec_2 = new double[size_vec * size_vec]; // Создание 2-го вектора
for (int count = 0; count < size_vec * size_vec; count++)
{
ptr_vec_2[count] = (rand() % 10 + 1) / double((rand() % 10 + 1)); // Заполнение вектора 2 случайными числами с масштабированием от 1 до 10
cout << ptr_vec_2[count] << " ";
}
cout << endl;
cout << endl;
tbb::task_scheduler_init init;
ScalarMultiplicator s(ptr_vec_1, ptr_vec_2); // Создаем объект класса
tbb::parallel_reduce(tbb::blocked_range<int>(0, size_vec * size_vec), s);
cout << "Result: " << s.Res() << endl;
// Для проверки: последовательное вычисление скалярного произведения
product_posled(ptr_vec_1, ptr_vec_2);
system("pause");
return 0;
}
// Для проверки: последовательное вычисление скалярного произведения
void product_posled(double *vec_1, double *vec_2)
{
double sum_all = 0.0;
for (int i = 0; i < size_vec * size_vec; i++)
{
sum_all += vec_1[i] * vec_2[i];
}
cout << "Result (posled): " << sum_all << endl;
} |