<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/a-very-experimental-threading-in-r/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://random-remarks.net/2016/12/11/a-very-experimental-threading-in-r/"> R – Random Remarks</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I’ve been trying to find a way to introduce threads to R. I guess there can be many reasons to do that, among which I could mention simplified input/output logic, sending tasks to the background (e.g. building a model asynchronously), running computation-intensive tasks in parallel (e.g. parallel, chunk-wise <code>var()</code> on a large vector). Finally, it’s just a neat problem to look at<img alt="😉" class="wp-smiley" src="https://i0.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f609.png?w=456&ssl=1" data-recalc-dims="1"> I’m trying to follow approach similar to Python’s <a target="_blank" rel="nofollow" href="https://wiki.python.org/moin/GlobalInterpreterLock">global interpreter lock</a>.</p>
<p>So far it seems that:</p>
<ul>
<li>one can re-enter the interpreter with <code>R_tryEval</code> which internally calls <code>R_ToplevelExec</code>, which in turn intercepts all long jumps (e.g. errors)</li>
<li>there are a few basic checks to verify whether the stack is in a good shape, e.g. <code>R_CStackStart</code> which checks stack frames and <code>R_PPStackTop</code> which checks objects under <code>PROTECT</code>ion</li>
</ul>
<p>I think that one can run multiple threads in R and maintain a separate interpreter “instance” in each of them. R interpreter uses stack for its bookkeeping and each thread has its own stack. It also counts objects excluded from garbage collection with <code>PROTECT</code>. Thus, when coming back to a given R interpreter “instance” (after thread-level context switch), one needs to pay attention to re-set <code>R_PPStackTop</code> to whatever that thread was left with.</p>
<p>I have put these ideas together in the form of a R package <a target="_blank" rel="nofollow" href="https://github.com/lbartnik/thread">thread</a> (GitHub). This is what it can do:</p>
<ul>
<li>start a new thread and execute a R function in its own interpreter</li>
<li>switch between threads on specific function calls, e.g. <code>thread_join()</code>, <code>thread_print()</code>, <code>thread_sleep()</code></li>
<li>finish thread execution</li>
<li>keep track of <code>R_PPStackTop</code></li>
<li>avoid SIGSEGV-faulting the R process<img alt="😉" class="wp-smiley" src="https://i0.wp.com/s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/72x72/1f609.png?w=456&ssl=1" data-recalc-dims="1"></li>
</ul>
<p>Here’s an example where two functions are run in parallel R threads (it’s also available via <code>thread::run_r_printing_example()</code>):</p>
<pre>library(thread)

thread_runner &lt;- function (data) {
  thread_print(paste(&quot;thread&quot;, data, &quot;starting\n&quot;))
  for (i in 1:10) {
    timeout &lt;- as.integer(abs(rnorm(1, 500, 1000)))
    thread_print(paste(&quot;thread&quot;, data, &quot;iteration&quot;, i,
                       &quot;sleeping for&quot;, timeout, &quot;\n&quot;))
    thread_sleep(timeout)
  }
  thread_print(paste(&quot;thread&quot;, data, &quot;exiting\n&quot;))
}
 
message(&quot;starting the first thread&quot;)
thread1 &lt;- new_thread(thread_runner, 1)
print(ls(threads))
 
message(&quot;starting the second thread&quot;)
thread2 &lt;- new_thread(thread_runner, 2)
print(ls(threads))
 
message(&quot;going to join() both threads&quot;)
thread_join(thread1)
thread_join(thread2)</pre>
<p>And here’s the output from my Ubuntu 16.10 x64:</p>
<pre>starting the first thread
[1] &quot;thread_140737231587072&quot;
starting the second thread
[1] &quot;thread_140737223194368&quot; &quot;thread_140737231587072&quot;
going to join() both threads
thread 1 starting
thread 1 iteration 1 sleeping for 144 
thread 2 starting
thread 2 iteration 1 sleeping for 587 
thread 1 iteration 2 sleeping for 761 
thread 2 iteration 2 sleeping for 1327 
thread 1 iteration 3 sleeping for 360 
thread 1 iteration 4 sleeping for 1802 
thread 2 iteration 3 sleeping for 704 
thread 2 iteration 4 sleeping for 463 
thread 1 iteration 5 sleeping for 368 
thread 2 iteration 5 sleeping for 977 
thread 1 iteration 6 sleeping for 261 
thread 1 iteration 7 sleeping for 323 
thread 1 iteration 8 sleeping for 571 
thread 2 iteration 6 sleeping for 509 
thread 2 iteration 7 sleeping for 2521 
thread 1 iteration 9 sleeping for 298 
thread 1 iteration 10 sleeping for 394 
thread 1 exiting
thread 2 iteration 8 sleeping for 966 
thread 2 iteration 9 sleeping for 533 
thread 2 iteration 10 sleeping for 1795 
thread 2 exiting</pre>
<p>How far is this from a real thread support in R? Well, there are three major challenges before this is really useful:</p>
<ul>
<li>Context switch happens only when a function from this package is called explicitly</li>
<li>Memory allocation needs to be synchronized</li>
<li>Error handling runs into <code>R_run_onexits</code> which in turn throws a very nasty error message – this suggests I haven’t covered all features of the interpreter related to switching stacks</li>
</ul>
<p>Issues #1 and #2 are related: one cannot leave R (release R interpreter lock) and enter an arbitrary C function because it is legal to call <code>allocVector()</code> from any C/C++ code. This in turn needs to happen synchronously – only one thread can execute <code>allocVector()</code> (or more specifically, <code>allocVector3()</code>) at any given time. I think that the best way to address it would be to patch R (<code>main/memory.c</code>) and introduce a pointer to <code>allocVector3</code> similar to <code>ptr_R_WriteConsole</code>). Then the thread package would inject a decorator for <code>allocVector3</code> with additional synchronization logic.</p>
<p>Issue #3 is not clear to me yet. But it also suggests more attention is needed to the specifics of R code execution.</p>
<p>I’ll be grateful for comments and suggestions. I think R could benefit from native thread support, if only to simplify program logic – but maybe also to run parts of computation-intensive code in lightweight parallel manner.</p>
<p> <a target="_blank" rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/randomremarksblog.wordpress.com/342/"><img alt="" src="http://feeds.wordpress.com/1.0/comments/randomremarksblog.wordpress.com/342/" border="0"></a> <img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://random-remarks.net/2016/12/11/a-very-experimental-threading-in-r/"> R – Random Remarks</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/eWbC9BfRLkQ"></a></div>