Ilość wątków - czasy wykonania programu

0

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 ?

0

Każdy wątek wykonuje to samo, czemu czasy wykonania tego samego kodu miały by się różnić?
Jeżeli masz 1000 rdzeni to wtedy 1000 wątków mogą wykonywać się równolegle.
Powinieneś mierzyć dla ilości wątków od 1 do 2*IlośćRdzeni.

5

Wszystkie funkcje func wykonują się synchronicznie, bo masz tam mutex lockera.

4

Na dodatek zasada "AS IF" powoduje, że ten kod:

    for (int j = 1000000 ; j ; --j) {
        for(int i = 0 ; i < 10; i++) {
            int x = i * j;
        }
    }

kompilator po prostu usunie, bo nie ma obserwowalnych wyników tego kodu.

Pokazałbym to na godbolt, ale obecnie usługa nie działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1