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

  • bashirsultani

    bashirsultan

    22 Mart 2010
  • Huot Media

    Huot Media

    7 Mayıs 2010
  • laptopmag

    laptopmag

    25 Ocak 2008