Rcpp11 3.1.2.0
Rcpp11 3.1.2.0 was released to CRAN, as the ultimate C++11 companion to R 3.1.2 on which it depends.
The NEWS extract follows:
# Rcpp11 3.1.2
* New `wrap` implementation for `std::tuple<Args...>` (#195)
* `colnames` and `rownames` setters for matrices (#210).
* Most sugar functions are now processing the expression in parallel.
* Forbidden symbols from the C/R API are no longer directly used,
so packages can use Rcpp11 without getting the NOTE as before.
This release marks departure from compromision. Rcpp11
used
to compromise on the meaning of C++11
to satisfy platforms for
which the available tooling was laging behind, most notoriously windows for
which the C++
compiler currently shipped with Rtools
only accomodates for some intermediate version called C++0x
.
As of this version, Rcpp11
truly requires C++11
and this is a feature. Of course it means that for some time,
users will have to install their own tool chain on windows.
This is not expected to last as there has been whispers about tool chain changes for R 3.2.0.
This has been fixed by @kevinushey and even though we are still using the functions, we do it in a way that does no longer trigger the NOTEs.
Another important change that is a direct consequence of no longer compromising
is that Rcpp11
now leverages hardware concurrency and some sugar
functions now process the expression in parallel.
This stack overflow thread has an example using the parallel sugar implementation of exp
.
Consider this R/C++
script, compatible with Rcpp
and Rcpp11
:
#include <Rcpp.h>
using namespace Rcpp ;
// [[Rcpp::export]]
NumericVector exp2(NumericVector x) {
NumericVector z = Rcpp::clone(x);
int n = z.size();
for (int i=0; i<n; ++i)
z[i] = exp(z[i]);
return z;
}
// [[Rcpp::export]]
NumericVector expSugar(NumericVector x) {
return exp(x) ;
}
/*** R
library(microbenchmark)
x <- rcauchy(1000000)
microbenchmark(exp(x), exp2(x), expSugar(x))
*/
Here are the result on my machine with the historical implementation of R/C++
:
> microbenchmark(exp(x), exp2(x), expSugar(x))
Unit: milliseconds
expr min lq median uq max neval
exp(x) 7.027006 7.222141 7.421041 8.631589 21.78305 100
exp2(x) 6.631870 6.790418 7.064199 8.145561 31.68552 100
expSugar(x) 6.491868 6.761909 6.888111 8.154433 27.36302 100
and here are the results with Rcpp11
:
> microbenchmark(exp(x), exp2(x), expSugar(x))
Unit: milliseconds
expr min lq median uq max neval
exp(x) 7.029882 7.077804 7.336214 7.656472 15.38953 100
exp2(x) 6.636234 6.748058 6.917803 7.017314 12.09187 100
expSugar(x) 1.652322 1.780998 1.962946 2.261093 12.91682 100
Now for a warning, Rcpp11
opts for a parallel version of
sugar expressions. It is the responsability of the developper to protect
against code that cannot run in parallel.
This can be done manually though mutexes, etc … but this is likely to lead to bad performance because of contention.
But this can also be done through the serial
function.
This function takes a sugar expression and returns another sugar expression
that is guaranteed to execute serially, in one thread.
Rcpp11
makes no attempt at figuring out if the expression can run in parallel.
This is the responsability of the developper of the code that uses it.