Cześć,
mam taki program:
#include <vector>
#include <thread>
#include <iostream>
#include <random>
#include <chrono>
#include <utility>
#include <future>
#include <algorithm>
using tt = std::pair<std::future<int>, std::thread>;
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void func(std::promise<int> && p) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
auto start = std::chrono::high_resolution_clock::now();
for (int j = 1000000 ; j ; --j) {
for(int i = 0 ; i < 10; i++) {
int x = i * j;
}
}
auto stop = std::chrono::high_resolution_clock::now();
p.set_value( std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count());
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
int mean(const std::vector<int>& v) {
if (v.size() ==0 ) return 0;
return std::accumulate( v.begin(), v.end(), 0.0) / v.size();
}
double percentbelow(const std::vector<int>& v, int th) {
double i = 0;
for (const auto& it : v) {
if(it < th) {
i++;
} else {
break;
}
}
return i/v.size();
}
int main(int argc, char** argv)
{
int thcount = std::stoi(argv[1]);
std::vector<tt> results;
for(int i = 0 ; i < thcount ; i++) {
std::promise<int> p;
auto f = p.get_future();
results.push_back(tt(std::move(f), std::thread(func, std::move(p))));
}
std::vector<int> times;
auto start = std::chrono::high_resolution_clock::now();
go();
for(auto& i : results) {
if(i.second.joinable()) i.second.join();
times.push_back(i.first.get());
}
auto stop = std::chrono::high_resolution_clock::now();
std::sort (times.begin(), times.end());
int av = mean(times);
int min = times[0];
int max = times[times.size()-1];
std::cout << "###################\nFor " << times.size() << " threads got: \n";
std::cout << "\n# whole: " << std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count() << "[ms]";
std::cout << "\n# mean: " << av << "[ms]";
std::cout << "\n# min: " << min << "[ms]";
std::cout << "\n# max: " << max << "[ms]";
std::cout << "\n# below mean: " << percentbelow(times, av) * 100 << " %";
std::cout << "\n# below 25 [ms]: " << percentbelow(times, 25)*100 << " % \n";
return 0;
}
Oczekiwałem, że im więcej wątków (powyżej pewnej ilości granicznej) to czas wykonania poszczególnych wątków będzie rósł. Nie zaobserwowałem czegoś takiego. Na komupterze z 8 corami mam takie wyniki:
$ ./a.out 2
**###################
For 2 threads got:
whole: 37[ms]
mean: 18[ms]
min: 18[ms]
max: 18[ms]
below mean: 0 %
below 25 [ms]: 100 %**
$ ./a.out 10
**###################
For 10 threads got:
whole: 193[ms]
mean: 18[ms]
min: 18[ms]
max: 20[ms]
below mean: 0 %
below 25 [ms]: 100 %**
$ ./a.out 100
**###################
For 100 threads got:
whole: 1891[ms]
mean: 18[ms]
min: 17[ms]
max: 21[ms]
below mean: 3 %
below 25 [ms]: 100 %**
$ ./a.out 500
**###################
For 500 threads got:
whole: 9322[ms]
mean: 18[ms]
min: 17[ms]
max: 20[ms]
below mean: 7 %
below 25 [ms]: 100 %**
$ ./a.out 1000
**###################
For 1000 threads got:
whole: 18637[ms]
mean: 18[ms]
min: 17[ms]
max: 25[ms]
below mean: 12.2 %
below 25 [ms]: 99.9 %**
Rośnie ogólny czas wykonania pomiaru (liniowo), ale poszczególne wątki maja czas ~const. Jak to tłumaczyć, i dlaczego ogólny czas tak rośnie ?