2014-10-09 7 views
9

मैं जंग के कार्यों के बारे में कुछ सीखना चाहता था, इसलिए मैंने पीआई के मोंटे कार्लो गणना किया। अब मेरी पहेली यही है कि एकल-थ्रेडेड सी संस्करण 4-तरफा थ्रेडेड जंग संस्करण की तुलना में 4 गुना तेजी से है। स्पष्ट रूप से मैं कुछ गलत कर रहा हूं, या मेरा मानसिक प्रदर्शन मॉडल रास्ता बंद है।जंग बनाम सी प्रदर्शन

यहाँ सी संस्करण है:

#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdio.h> 

#define PI 3.1415926535897932 

double monte_carlo_pi(int nparts) 
{ 
    int i, in=0; 
    double x, y; 
    srand(getpid()); 

    for (i=0; i<nparts; i++) { 
     x = (double)rand()/(double)RAND_MAX; 
     y = (double)rand()/(double)RAND_MAX; 

      if (x*x + y*y < 1.0) { 
      in++; 
     } 
    } 

    return in/(double)nparts * 4.0; 
} 

int main(int argc, char **argv) 
{ 
    int nparts; 
    double mc_pi; 

    nparts = atoi(argv[1]); 
    mc_pi = monte_carlo_pi(nparts); 
    printf("computed: %f error: %f\n", mc_pi, mc_pi - PI); 
} 

जंग संस्करण एक पंक्ति-दर-पंक्ति बंदरगाह नहीं था:

use std::rand; 
use std::rand::distributions::{IndependentSample,Range}; 

fn monte_carlo_pi(nparts: uint) -> uint { 
    let between = Range::new(0f64,1f64); 
    let mut rng = rand::task_rng(); 
    let mut in_circle = 0u; 
    for _ in range(0u, nparts) { 
     let a = between.ind_sample(&mut rng); 
    let b = between.ind_sample(&mut rng); 

    if a*a + b*b <= 1.0 { 
     in_circle += 1; 
    } 
    } 
    in_circle 
} 

fn main() { 
    let (tx, rx) = channel(); 

    let ntasks = 4u; 
    let nparts = 100000000u; /* I haven't learned how to parse cmnd line args yet!*/ 
    for _ in range(0u, ntasks) { 
     let child_tx = tx.clone(); 
     spawn(proc() { 
     child_tx.send(monte_carlo_pi(nparts/ntasks)); 
     }); 
    } 

    let result = rx.recv() + rx.recv() + rx.recv() + rx.recv(); 

    println!("pi is {}", (result as f64)/(nparts as f64)*4.0); 
} 

बिल्ड और समय सी संस्करण:

$ clang -O2 mc-pi.c -o mc-pi-c; time ./mc-pi-c 100000000 
computed: 3.141700 error: 0.000108 
./mc-pi-c 100000000 1.68s user 0.00s system 99% cpu 1.683 total 

जंग का संस्करण बनाएं और समय बनाएं:

$ rustc -v  
rustc 0.12.0-nightly (740905042 2014-09-29 23:52:21 +0000) 
$ rustc --opt-level 2 --debuginfo 0 mc-pi.rs -o mc-pi-rust; time ./mc-pi-rust 
pi is 3.141327 
./mc-pi-rust 2.40s user 24.56s system 352% cpu 7.654 tota 
+0

प्रोफाइलर क्या कहता है? (यानी: आपके कोड में हॉटस्पॉट और बाधाओं को ढूंढना सीखने के लिए यह एक अच्छा सबक है)। – Necrolis

+2

डीबगिंग प्रतीकों के साथ संकलित न करें। – AndyG

+11

'एकल-थ्रेडेड सी संस्करण 4-तरफा थ्रेडेड जंग संस्करण की तुलना में 4 गुना धीमा है। आपके द्वारा पोस्ट की गई संख्या –

उत्तर

9

डॉगबर्ट के रूप में बाधा, यादृच्छिक संख्या जनरेटर था। यहां एक ऐसा है जो प्रत्येक थ्रेड पर तेज़ और बीजित होता है

fn monte_carlo_pi(id: u32, nparts: uint) -> uint { 
    ... 
    let mut rng: XorShiftRng = SeedableRng::from_seed([id,id,id,id]); 
    ... 
} 
संबंधित मुद्दे