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

Ilość wątków - czasy wykonania programu
GG
  • Rejestracja:ponad 11 lat
  • Ostatnio:około 3 lata
  • Postów:10
0

Cześć,

mam taki program:

Kopiuj
#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 ?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 dni
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.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
5

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


MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
4

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

Kopiuj
    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.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.