Hallo,
Als test voor mezelf om te kijken of ik multi-threading goed kon implementeren heb ik een klein programma geschreven.
Het programma genereert een hoop random reeksen van 0'n en 1'n. De kans op een 1 is p, op een 0 is 1-p. Deze reeksen worden opgedeeld is series van 0'n en 1'n. Bijvoorbeeld 11110001101 heeft 5 deelseries: 1111, 000, 11, 0 en 1. Vervolgens wordt er gekeken naar de gemiddelde lengte van de tweede deelserie.
Een simpel rekensommetje leert dat gegeven genoeg reeksen dat ongeveer 2 is (ongeacht van p).
Wat ik nu probeer is de computer dit zo snel mogelijk uit te laten rekenen voor veel reeksen. In de eerste instantie had ik een singlethread implementatie die redelijk snel was, maar ik dacht dat als ik de reeksen verdeel over meerdere threads (stel t threads) het sneller zou moeten gaan met een factor t. Helaas is dit niet het geval en is het zelfs veel langzamer dan in het singlethread geval.
Weet een van jullie wat er mis gaat?
Dit is mijn code:
Als test voor mezelf om te kijken of ik multi-threading goed kon implementeren heb ik een klein programma geschreven.
Het programma genereert een hoop random reeksen van 0'n en 1'n. De kans op een 1 is p, op een 0 is 1-p. Deze reeksen worden opgedeeld is series van 0'n en 1'n. Bijvoorbeeld 11110001101 heeft 5 deelseries: 1111, 000, 11, 0 en 1. Vervolgens wordt er gekeken naar de gemiddelde lengte van de tweede deelserie.
Een simpel rekensommetje leert dat gegeven genoeg reeksen dat ongeveer 2 is (ongeacht van p).
Wat ik nu probeer is de computer dit zo snel mogelijk uit te laten rekenen voor veel reeksen. In de eerste instantie had ik een singlethread implementatie die redelijk snel was, maar ik dacht dat als ik de reeksen verdeel over meerdere threads (stel t threads) het sneller zou moeten gaan met een factor t. Helaas is dit niet het geval en is het zelfs veel langzamer dan in het singlethread geval.
Weet een van jullie wat er mis gaat?
Dit is mijn code:
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
| /** * Dit is een simulatie van een reeks 0'n en 1'n. * Er wordt geteld hoe lang de tweede deelreeks gemiddeld is gegeven de kans op een 1 p is. * (eg in de reeks 1110001 is de lengte van de tweede deelreeks gelijk aan 3) */ #include <cmath> #include <cstdlib> #include <iostream> #include <sstream> #include <vector> #include <pthread.h> using namespace std; int i, p, n; vector <int> c; void * run (void * _x) { int x = *(int*) _x; for (int i = x; i < n; i++) { if (c[i] > 0) return NULL; c[i] = 0; bool run = true; bool last; int k = rand() % 10000; if (k > p) last = true; else last = false; while (run) { k = rand() % 10000; if (k > p) { if (!last) run = false; } else { if (last) run = false; } } last = !last; run = true; while (run) { c[i]++; k = rand() % 10000; if (k > p) { if (!last) run = false; } else { if (last) run = false; } } } } int main (int argc, char *argv[]) { cout.setf(ios::fixed); cout.precision(9); // Laden van alle data int s, t; if (argc == 5) { stringstream buffer; buffer << argv[1] << ' ' << argv[2] << ' ' << argv[3] << ' ' << argv[4]; buffer >> p >> n >> s >> t; } else { p = 0; n = 0; s = 0; t = 0; } while (p < 0 || 10000 < p || n < 1 || 1000000 < n || s < 0 || t < 0) { cout << "Select a (integer) value for p [0-10000]: "; cin >> p; cout << "Select a (integer) value for n [1-1000000]: "; cin >> n; cout << "Select a (integer) value for s [>0]: "; cin >> s; cout << "Select a (integer) value for t [>0]: "; cin >> t; } // De test c.resize(n); pthread_t threads[t]; i = 0; srand(s); int pt = n / t; int * px = NULL; for (int i = 0; i < t; i++) { px = new int; (*px) = pt * i; pthread_create(&threads[i], NULL, run, px); } for (int i = 0; i < t; i++) pthread_join(threads[i], NULL); // Verwerken van alle data double avg = 0; for (int i = 0; i < n; i++) avg += c[i]; avg = avg/n; double var = 0; for (int i = 0; i < n; i++) var += pow((c[i] - avg), 2); var = var/n; cout << "Mean: " << avg << " Variance: " << var << endl; return 0; } |