Ticket #1962: thread4.cpp

File thread4.cpp, 2.7 KB (added by Dave Abrahams, 14 years ago)
Line 
1// Copyright David Abrahams 2008. Distributed under the Boost
2// Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4#include "boost/thread.hpp"
5#include "boost/iterator/counting_iterator.hpp"
6#include "boost/lambda/lambda.hpp"
7#include "boost/lambda/bind.hpp"
8#include "boost/timer.hpp"
9#include "boost/type_traits/remove_const.hpp"
10#include "boost/type_traits/remove_reference.hpp"
11#include "boost/array.hpp"
12#include "boost/date_time/local_time/local_time.hpp"
13#include <vector>
14#include <iterator>
15#include <numeric>
16#include <algorithm>
17#include <cmath>
18#include <iostream>
19
20namespace my
21{
22double sqrt(double x)
23{
24 return std::sqrt(x);
25}
26}
27
28// sum terms [i-j) of the power series for pi/4
29double calc(std::size_t i, std::size_t j)
30{
31 double sum = 0.0;
32
33 while (i < j)
34 {
35 sum += (i % 2 == 0 ? 1.0 : -1.0) / (2*i + 1);
36 ++i;
37 }
38 return sum;
39}
40
41std::size_t const max_parallelism = 20;
42typedef boost::array<boost::thread, max_parallelism> thread_pool;
43typedef boost::array<double, max_parallelism> result_pool;
44
45double calc_pi(std::size_t nterms, std::size_t parallelism, thread_pool& threads, result_pool& results)
46{
47 assert(parallelism > 0 && parallelism <= threads.size()); // make sure we've allocated enough space
48 assert(threads.size() == results.size()); // make sure we've allocated enough space
49
50 using namespace boost::lambda;
51 double const step = nterms * 1.0 / parallelism;
52 for (int i = 1; i < parallelism; ++i)
53 {
54 threads[i] = boost::thread(
55 var(results[i]) = bind(calc, i * step, (i+1) * step)
56 );
57 }
58
59 // do a calculation in this thread
60 results[0] = calc(0, step);
61
62 // wait for all threads to finish
63 for (int i = 1; i < parallelism; ++i)
64 threads[i].join();
65
66 return std::accumulate( results.begin(), results.begin() + parallelism, 0.0 );
67}
68
69
70
71int main()
72{
73 std::size_t const n = 200000000;
74
75
76 thread_pool threads;
77 result_pool results;
78
79 std::cout << "warming up the cache..." << std::endl;
80 double pi = 4*calc_pi(n, 4, threads, results);
81 std::cout << "start" << std::endl;
82
83 for (std::size_t p = 1; p < max_parallelism; ++p)
84 {
85 using namespace boost::gregorian;
86 using namespace boost::posix_time;
87 using namespace boost::local_time;
88
89 ptime start = microsec_clock::local_time();
90 boost::timer time;
91
92 pi = 4*calc_pi(n, p, threads, results);
93 microsec_clock::time_duration_type t0 = microsec_clock::local_time() - start;
94 double t1 = time.elapsed();
95
96 std::cout << "calculating pi = " << pi << " using " << p << " threads took: " << t0 << " but timer reports: " << t1 << std::endl;
97 }
98}