Loading [MathJax]/extensions/tex2jax.js
Parallel numerical verification of the σ_odd problem  October 6, 2018
All Classes Namespaces Files Functions Variables Typedefs Macros
benchmarks.cpp
Go to the documentation of this file.
1 /* -*- coding: latin-1 -*- */
2 /** \file common/benchmarks.cpp (January 5, 2018)
3  * \brief
4  * Some benchmarks for the sigma_odd problem.
5  *
6  * GPLv3 --- Copyright (C) 2017, 2018 Olivier Pirson
7  * http://www.opimedia.be/
8  */
9 
10 // \cond
11 #include <cstdlib>
12 
13 #include <algorithm>
14 #include <chrono>
15 #include <iostream>
16 // \endcond
17 
18 #include "helper/helper.hpp"
19 #include "sigmaodd/pentagonal.hpp"
20 #include "sigmaodd/primes.hpp"
21 #include "sigmaodd/sigmaodd.hpp"
22 
23 
24 
25 /* ***********
26  * Prototype *
27  *************/
28 
29 void
31 
32 
33 
34 /* **********
35  * Function *
36  ************/
37 
38 void
40  std::cerr << "Usage: benchmarks [option]" << std::endl
41  << std::endl
42  << "Option:" << std::endl
43  << " --nb -n number of odd numbers to check by range (100 by default)" << std::endl;
44 
45  exit(EXIT_FAILURE);
46 }
47 
48 
49 
50 /* ******
51  * Main *
52  ********/
53 
54 int
55 main(int argc, const char* const argv[]) {
56  // Load primes table
58  std::cerr << "! Impossible to load \"" << sigmaodd::prime_filename << '"' << std::endl
59  << std::endl;
60  help_and_exit();
61  }
62 
63 
64  std::srand(666); // to have deterministic "random" numbers
65 
66  sigmaodd::nat_type nb = 100;
67 
68  // Read command line parameters
69  for (unsigned int i = 1; i < static_cast<unsigned int>(argc); ++i) {
70  const std::string param(argv[i]);
71 
72  if (param == "--nb") {
73  nb = helper::get_ulong(argc, argv, ++i, &help_and_exit);;
74  }
75  else {
76  help_and_exit();
77  }
78  }
79 
80 
81  // Print intern configuration
83 
84 
85  // Print parameter
86  std::cout << "Nb: " << nb << std::endl;
87 
88 
89  // Print table legend
90  std::cout << std::endl
91  << "First n\tLast n\tNb\tNaive\tFactorize\tFactorize bound\tEuler"
92  << std::endl;
93  std::cout.flush();
94 
95 
96  // Main calculation
97  const sigmaodd::nat_type firsts[] = {3,
98  11,
99  101,
100  1001, // 10^3 = 1,000
101  10001,
102  100001,
103  1000001, // 10^6 = 1,000,000
104  10000001,
105  100000001,
106  1000000001, // 10^9 = 1,000,000,000
107  10000000001,
108  100000000001,
109  1000000000001, // 10^12 = 1,000,000,000,000
110  10000000000001,
111  100000000000001,
112  1000000000000001, // 10^15 = 1,000,000,000,000,000
113  10000000000000001};
114  const unsigned int firsts_nb = sizeof(firsts)/sizeof(sigmaodd::nat_type);
115 
116  std::chrono::duration<double> total_duration = std::chrono::duration<double>(0);
117 
118  for (sigmaodd::nat_type i = 0; i < firsts_nb; ++i) {
119  const sigmaodd::nat_type first = firsts[i];
120  const sigmaodd::nat_type last = (i + 1 < firsts_nb
121  ? std::min(firsts[i + 1] - 2, first + (nb - 1)*2)
122  : first + nb*2);
123  const sigmaodd::nat_type current_nb = (last - first)/2 + 1;
124 
125  // Coefficient to convert seconds -> microseconds and divide by #
126  const unsigned int repeat = (last < 100000
127  ? 10000
128  : 1);
129  const double duration_coef = 1000000.0;
130 
131  assert(sigmaodd::is_odd(first));
132  assert(sigmaodd::is_odd(last));
133 
134  std::cout << first << '\t' << last << '\t' << current_nb;
135  std::cout.flush();
136 
137  // Naive
138  if (first <= 100000000000000) { // 10^14 = 100,000,000,000,000
139  sigmaodd::nat_type real_nb = 0;
140  const std::chrono::steady_clock::time_point clock_start = std::chrono::steady_clock::now();
141 
142  for (unsigned int k = 0; k < repeat; ++k) {
143  for (sigmaodd::nat_type n = first; n <= last; n += 2) {
145  continue;
146  }
147 
148  ++real_nb;
149 
150 #pragma GCC diagnostic push
151 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
152  volatile const std::pair<sigmaodd::nat_type, unsigned int> result_length
154 #pragma GCC diagnostic pop
155  }
156  }
157 
158  const std::chrono::duration<double> duration = std::chrono::steady_clock::now() - clock_start;
159 
160  std::cout << '\t' << duration.count()*duration_coef/static_cast<double>(real_nb);
161  total_duration += duration;
162  }
163  else {
164  std::cout << '\t';
165  }
166  std::cout.flush();
167 
168  // Factorize
169  {
170  sigmaodd::nat_type real_nb = 0;
171  const std::chrono::steady_clock::time_point clock_start = std::chrono::steady_clock::now();
172 
173  for (unsigned int k = 0; k < repeat; ++k) {
174  for (sigmaodd::nat_type n = first; n <= last; n += 2) {
176  continue;
177  }
178 
179  ++real_nb;
180 
181 #pragma GCC diagnostic push
182 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
183  volatile const std::pair<sigmaodd::nat_type, unsigned int> result_length
185 #pragma GCC diagnostic pop
186  }
187  }
188 
189  const std::chrono::duration<double> duration = std::chrono::steady_clock::now() - clock_start;
190 
191  std::cout << '\t' << duration.count()*duration_coef/static_cast<double>(real_nb);
192  total_duration += duration;
193  }
194  std::cout.flush();
195 
196  // Factorize bound
197  {
198  sigmaodd::nat_type real_nb = 0;
199  const std::chrono::steady_clock::time_point clock_start = std::chrono::steady_clock::now();
200 
201  for (unsigned int k = 0; k < repeat; ++k) {
202  for (sigmaodd::nat_type n = first; n <= last; n += 2) {
204  continue;
205  }
206 
207  ++real_nb;
208 
209 #pragma GCC diagnostic push
210 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
211  volatile const std::pair<sigmaodd::nat_type, unsigned int> result_length
213 #pragma GCC diagnostic pop
214  }
215  }
216 
217  const std::chrono::duration<double> duration = std::chrono::steady_clock::now() - clock_start;
218 
219  std::cout << '\t' << duration.count()*duration_coef/static_cast<double>(real_nb);
220  total_duration += duration;
221  }
222 
223  // Euler
225  sigmaodd::nat_type real_nb = 0;
226  const std::chrono::steady_clock::time_point clock_start = std::chrono::steady_clock::now();
227 
228  for (unsigned int k = 0; k < repeat; ++k) {
229  for (sigmaodd::nat_type n = first; n <= last; n += 2) {
231  continue;
232  }
233 
234  ++real_nb;
235 
236 #pragma GCC diagnostic push
237 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
238  volatile const std::pair<sigmaodd::nat_type, unsigned int> result_length
240 #pragma GCC diagnostic pop
241  }
242  }
243 
244  const std::chrono::duration<double> duration = std::chrono::steady_clock::now() - clock_start;
245 
246  std::cout << '\t' << duration.count()*duration_coef/static_cast<double>(real_nb);
247  total_duration += duration;
248  }
249 
250  std::cout << std::endl;
251  }
252 
253  std::cerr << "Total duration (for all calculation): "
254  << helper::duration_to_string(total_duration)
255  << std::endl;
256 
257  return EXIT_SUCCESS;
258 }
int main(int argc, const char *const argv[])
Definition: benchmarks.cpp:55
uint64_t nat_type
Type for natural number used in all code, on 64 bits.
Definition: helper.hpp:33
constexpr bool is_odd(nat_type n)
Return true iff n is odd.
std::pair< nat_type, unsigned int > sum_odd_divisors_divided_until_odd_iterate_until_lower__factorize(nat_type n)
Iterates the sum_odd_divisors_divided_until_odd__factorize() function from n until have a result lowe...
Definition: sigmaodd.cpp:712
const std::string prime_filename
Default filename for the binary file "big_data/prime28.bin".
Definition: primes.cpp:35
Functions to calculate pentagonal numbers and one useless algorithm that used the Euler formula to ca...
std::pair< nat_type, unsigned int > sum_odd_divisors_divided_until_odd_iterate_until_lower__factorize_bound(nat_type n)
Iterates the sum_odd_divisors_divided_until_odd__factorize() function from n until have a result lowe...
Definition: sigmaodd.cpp:731
std::string duration_to_string(std::chrono::duration< double > duration_second)
Return a string with the duration expressed in milliseconds, seconds, minutes and hours...
Definition: helper.cpp:61
std::size_t sum_divisors__euler_cache_nb()
Return the current number of items in the cache used by sum_divisors__euler()
Definition: pentagonal.cpp:158
std::pair< nat_type, unsigned int > sum_odd_divisors_divided_until_odd_iterate_until_lower__euler(nat_type n)
Iterates the sum_odd_divisors_divided_until_odd__euler() function from n until have a result lower th...
Definition: sigmaodd.cpp:693
bool read_primes_table()
Read the binary file prime_filename to fill the table with all primes < 2^28. This table must be read...
Definition: primes.cpp:241
void help_and_exit()
Definition: benchmarks.cpp:39
Functions to access to tables of precaculated prime numbers and offsets to iterate on possible prime ...
std::pair< nat_type, unsigned int > sum_odd_divisors_divided_until_odd_iterate_until_lower__naive(nat_type n)
Iterates the sum_odd_divisors_divided_until_odd__naive() function from n until have a result lower th...
Definition: sigmaodd.cpp:750
Some generic helper functions for programs.
void print_intern_config_compiler()
Print to stdcout the intern configuration of the compiler.
Definition: helper.cpp:148
constexpr bool is_little_mersenne_prime_unitary_divide(nat_type n)
Return true iff at least one of 3, 7, 31, 127, 8191, 131071 or 524287 is an unitary divisor of n...
Main functions to deal the sigma_odd problem.
unsigned long get_ulong(int argc, const char *const argv[], unsigned int i, void(*help_and_exit_function)())
Return argv[i] converted in integer.
Definition: helper.cpp:124