iota.lib.cpp
IOTA C++ Library
parallel_for.hpp
1 //
2 // MIT License
3 //
4 // Copyright (c) 2017-2018 Thibault Martinez and Simon Ninon
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //
24 //
25 
26 #pragma once
27 
28 #include <atomic>
29 #include <future>
30 #include <vector>
31 
32 namespace IOTA {
33 
34 namespace Utils {
35 
36 template <typename F>
37 void
38 parallel_for(std::size_t begin, std::size_t end, F fn) {
39  std::atomic<std::size_t> idx(begin);
40  int num_cpus = std::thread::hardware_concurrency();
41  std::vector<std::future<void>> futures(num_cpus);
42 
43  for (int cpu = 0; cpu != num_cpus; ++cpu) {
44  futures[cpu] = std::async(std::launch::async, [&idx, end, &fn]() {
45  for (;;) {
46  std::size_t i = idx++;
47  if (i >= end)
48  break;
49  fn(i);
50  }
51  });
52  }
53  for (int cpu = 0; cpu != num_cpus; ++cpu) {
54  futures[cpu].get();
55  }
56 }
57 
58 template <typename F>
59 void
60 parallel_for(int threads, F fn) {
61  int num_cpus = threads == 0 ? std::thread::hardware_concurrency() : threads;
62  std::vector<std::future<void>> futures(num_cpus);
63 
64  for (int cpu = 0; cpu != num_cpus; ++cpu) {
65  futures[cpu] = std::async(std::launch::async, fn, cpu, num_cpus);
66  }
67  for (int cpu = 0; cpu != num_cpus; ++cpu) {
68  futures[cpu].get();
69  }
70 }
71 
72 } // namespace Utils
73 
74 } // namespace IOTA
Definition: core.hpp:33