SORU
23 Mayıs 2013, PERŞEMBE


Neden C 11 bu kodu içeren rand() ile birden çok iş parçacığı ile daha yavaş?

Yeni C 11 konuları üzerinde çalışıyorum, ama benim basit bir test dipsiz çok çekirdekli performans vardır. Basit bir örnek olarak, bu program, bazı Kare rasgele sayılar ekler.

#include <iostream>
#include <thread>
#include <vector>
#include <cstdlib>
#include <chrono>
#include <cmath>

double add_single(int N) {
    double sum=0;
    for (int i = 0; i < N;   i){
        sum = sqrt(1.0*rand()/RAND_MAX);
    }
    return sum/N;
}

void add_multi(int N, double& result) {
    double sum=0;
    for (int i = 0; i < N;   i){
        sum = sqrt(1.0*rand()/RAND_MAX);
    }
    result = sum/N;
}

int main() {
    srand (time(NULL));
    int N = 1000000;

    // single-threaded
    auto t1 = std::chrono::high_resolution_clock::now();
    double result1 = add_single(N);
    auto t2 = std::chrono::high_resolution_clock::now();
    auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count();
    std::cout << "time single: " << time_elapsed << std::endl;

    // multi-threaded
    std::vector<std::thread> th;
    int nr_threads = 3;
    double partual_results[] = {0,0,0};
    t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < nr_threads;   i) 
        th.push_back(std::thread(add_multi, N/nr_threads, std::ref(partual_results[i]) ));
    for(auto &a : th)
        a.join();
    double result_multicore = 0;
    for(double result:partual_results)
        result_multicore  = result;
    result_multicore /= nr_threads;
    t2 = std::chrono::high_resolution_clock::now();
    time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count();
    std::cout << "time multi: " << time_elapsed << std::endl;

    return 0;
}

'G -std=c 11 -pthread test.cpp' Linux ve 3core bir makinede, tipik bir sonucudur . derlenmiş

time single: 33
time multi: 565

Yani çok dişli bir sürüm büyüklüğü yavaş bir sipariş daha. Rasgele sayılar ve örnek ve derleyici en iyi duruma getirmeleri için daha az önemsiz gören bir Karekök kullandım, hiç bi fikrim yok.

edit:

  1. Bu sorun kısa çalışma zamanı değil, çok büyük N için ölçeklendirir
  2. Bu iş parçacığı oluşturmak için zaman sorun değil. Hariç olmak üzere, sonuç çok fazla değişmez

Vay be sorunu buldum. Aslında rand(). C 11 eşdeğer ve zamanı ölçekler mükemmel şimdi ile yer değiştirdi. Herkese teşekkürler!

CEVAP
23 Mayıs 2013, PERŞEMBE


Benim sistem davranış aynı ama Maxim belirtildiği gibi, rand iş parçacığı güvenli değil. Rand_r, o zaman çok dişli bir kod rand değiştirdiğimde beklendiği gibi daha hızlı.

void add_multi(int N, double& result) {
double sum=0;
unsigned int seed = time(NULL);
for (int i = 0; i < N;   i){
    sum = sqrt(1.0*rand_r(&seed)/RAND_MAX);
}
result = sum/N;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AlaskanGrizzly

    AlaskanGrizz

    30 EKİM 2009
  • Noam Erez

    Noam Erez

    3 NİSAN 2012
  • The10HourMan

    The10HourMan

    28 EYLÜL 2012