Bonjour,
je débute avec TBB. J'ai écrit une série de fonctions/classes pour calculer un écart type.
Comparé à la même méthode mais linéaire, la méthode TBB opère en un peu moins de 60% du temps (avec un core 2 duo). Donc tout me semble fonctionner correctement mais j'utilisais des tableaux standards dans la première version du code.

J'ai voulu remplacer les tableaux par des vector et là les performances sont passées de 60 à 80%. Cela reste plus rapide que la version linéaire mais pourquoi une telle différence ? Avez-vous une idée ?

Voici le code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
 
#include <iostream>
#include <string>
#include <vector>
 
#include <stdlib.h>		//rand
#include <math.h>		//sqrt
 
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/tick_count.h"
 
 
 
template <typename T>
class FSum {
	T *array_;
	T *sum_;
public:
	FSum (T *array, T *sum) : array_(array), sum_(sum) {
		*sum_ = T(0);
	}
	void operator () (const tbb::blocked_range<size_t> &r) const {
		T *ptr = array_+r.begin();
		T *array_end = array_+r.end();
		T s=T(0);
		for (; ptr!=array_end; ++ptr)
			s += *ptr;
		*sum_ += s;
	}
};
 
template <typename T>
class FVar {
	T *array_;
	T *mean_;
	T *sum_;
public:
	FVar (T *array, T *mean, T*sum) : array_(array), mean_(mean), sum_(sum) {
		*sum_ = T(0);
	}
	void operator () (const tbb::blocked_range<size_t> &r) const {
		T *ptr = array_+r.begin();
		T *array_end = array_+r.end();
		T S=T(0);
		T s;
		for (; ptr!=array_end; ++ptr) {
			s = *ptr-*mean_;
			S += s*s;
		}
		*sum_ += S;
	}
};
 
template <typename T>
std::vector<T> getArray (std::size_t N) {
	std::vector<T> array(N);
	for (std::size_t i=0; i<N; ++i)
		array.push_back (T(rand()%1000));
	return array;
}
 
template <typename T>
T getStdDev_tbb (std::vector<T> array, std::size_t n=1e6) {
	T res=T(0);
	T mean=T(0);
	T var=T(0);
 
	tbb::parallel_for (tbb::blocked_range<size_t> (0, array.size(), n),
					   FSum<T> (&(array[0]),&res));
 
	mean = res/T(array.size());
 
	tbb::parallel_for (tbb::blocked_range<size_t> (0, array.size(), n),
					   FVar<T> (&(array[0]),&mean,&res));
 
	var = res/T(array.size()-1);
 
	return T(sqrt(var));
}
 
 
template <typename T>
T getStdDev (std::vector<T> array) {
	T sum=T(0);
	T mean=T(0);
	T var=T(0);
 
 
	T *ptr = &(array[0]);
	T *array_end = ptr+array.size();
	for (; ptr!=array_end; ++ptr)
		sum += *ptr;
 
	mean = sum/T(array.size());
 
	sum = T(0);
 
	ptr = &(array[0]);
	array_end = ptr+array.size();
	for (; ptr!=array_end; ++ptr) {
		T s = *ptr-mean;
		sum += s*s;
	}
 
	var = sum/T(array.size()-1);
 
 
	return T(sqrt(var));
}
 
template <typename T>
void test (std::size_t N, int n) {
 
	std::vector<T> array = getArray<T>(N);
 
	tbb::tick_count t0 = tbb::tick_count::now();
	for (int i=0; i<n; i++)
		getStdDev<T>(array);
 
	tbb::tick_count t1 = tbb::tick_count::now();
	for (int i=0; i<n; i++)
		getStdDev_tbb<T>(array);
 
	tbb::tick_count t2 = tbb::tick_count::now();
 
	float duration0 = (t1-t0).seconds();
	float duration1 = (t2-t1).seconds();
 
	std::cout << duration0 << "\t100%" << std::endl;
	std::cout << duration1 << "\t" << 100.0f*(duration1/duration0) << "%" << std::endl;
 
}
 
int main(int argc, char *argv[]) {
 
	test<unsigned int> (1e8,2);
 
	return 0;
}