2009-09-14 2 views
2

Dans l'exemple suivant (chapitre 2), Anthony Williams tente de paralléliser la fonction d'accumulation standard. ma question est pourquoi fait-il ceci:Une confusion à propos de parallel_accumulate dans C++ Concurrency en action

unsigned long const max_threads=(length+min_per_thread-1)/min_per_thread; 

pourquoi ajouter la longueur et soustraire 1? pourquoi pas seulement:

unsigned long const max_threads=length/min_per_thread; 

...................................... .............................................

template<typename Iterator,typename T> 
    struct accumulate_block 
    { 
      void operator()(Iterator first,Iterator last,T& result) 
      { 
       result=std::accumulate(first,last,result); 
      } 
    }; 


    template<typename Iterator,typename T> 
    T parallel_accumulate(Iterator first,Iterator last,T init) 
    { 
      unsigned long const length=std::distance(first,last); 
      if(!length) 
       return init; 

      unsigned long const min_per_thread=25; 
      unsigned long const max_threads=(length+min_per_thread-1)/min_per_thread; 

      unsigned long const hardware_threads=std::thread::hardware_concurrency(); 
      unsigned long const num_threads= 
      std::min(hardware_threads!=0?hardware_threads:2,max_threads); 

     unsigned long const block_size=length/num_threads; 

     std::vector<T> results(num_threads); 
     std::vector<std::thread> threads(num_threads-1); 
     Iterator block_start=first; 
     for(unsigned long i=0;i<(num_threads-1);++i) 
     { 
      Iterator block_end=block_start; 
      std::advance(block_end,block_size); #6 
      threads[i]=std::thread(accumulate_block<Iterator,T>(),  
           block_start,block_end,std::ref(results[i])); 
      block_start=block_end; 
     } 
     accumulate_block()(block_start,last,results[num_threads-1]); 
     std::for_each(threads.begin(),threads.end(), 
     std::mem_fn(&std::thread::join)); 

     return std::accumulate(results.begin(),results.end(),init); 
    } 
+0

Je suppose que vous vouliez dire 'longueur/min_per_thread', pas' (min_per_thread)/min_per_thread' –

+0

C'est exact! – vehomzzz

Répondre

5

le problème avec l'utilisation

unsigned long const max_threads=length/min_per_thread; 

est causée par l'arrondi de troncature utilisé lors de la division entière

si

length = 7 
min_per_thread = 5 

puis

max_threads = length/min_per_thread = 1 

tandis que les Threads max devraient effectivement être 2

length + min_per_thread - 1 = 11 

max_threads = (length + min_per_thread - 1)/min_per_thread = 2