-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcount_positive.cpp
More file actions
68 lines (52 loc) · 1.74 KB
/
count_positive.cpp
File metadata and controls
68 lines (52 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <Rcpp.h>
#include <thread>
#include <future>
using namespace Rcpp ;
typedef NumericVector::iterator Iterator ;
inline int count_positive_range(Iterator begin, Iterator end){
return std::count_if( begin, end,
[](double d){ return d > 0 ;}
) ;
}
// [[Rcpp::export]]
int count_positive_serial(NumericVector x){
return count_positive_range( x.begin(), x.end() ) ;
}
// [[Rcpp::export]]
int count_positive_2threads(NumericVector x){
int n = x.size() ;
Iterator it = x.begin() ;
std::packaged_task<int(Iterator,Iterator)> task( &count_positive_range ) ;
std::future<int> first_half = task.get_future() ;
std::thread t( std::move(task), it, it+n/2 ) ;
int second_half = count_positive_range(it+n/2, x.end() ) ;
t.join() ;
return first_half.get() + second_half ;
}
typedef std::packaged_task<int(Iterator,Iterator)> Task ;
// [[Rcpp::export]]
int count_positive_threaded(NumericVector data, int nthreads){
int n = data.size() ;
int chunk_size = n / nthreads ;
std::vector<std::future<int>> futures(nthreads-1) ;
std::vector<std::thread> threads(nthreads-1) ;
Iterator it = data.begin() ;
for( int i=0; i<nthreads-1; i++){
Task task(&count_positive_range) ;
futures[i] = task.get_future();
threads[i] = std::thread( std::move(task), it, it + chunk_size ) ;
it += chunk_size ;
}
int result = count_positive_range(it, data.end());
for( int i=0; i<nthreads-1; i++) {
threads[i].join() ;
result += futures[i].get() ;
}
return result ;
}
/*** R
v <- rnorm(1e9)
system.time( count_positive_serial(v) )
system.time( count_positive_2threads(v) )
system.time( count_positive_threaded(v,4) )
*/