Skip to content

Commit

Permalink
Benchmark R future globals=FALSE
Browse files Browse the repository at this point in the history
In the prior commit I looked into why R overhead was so high for future
calls. The marginal cost of a foreign call to Python is only 3ms, but
for R this was 70ms. I found this improved 2-3 fold by setting
globals=FALSE in the `future` call. This tells `future` not to search
global variables to pass to the new R instances. Using the multicore
plan, a fork of the original R program is made for each new worker, the
workers may be reused when they complete their jobs. With every new job,
they may need to the latest global information. `future` will search for
that information is `globals=TRUE`. Otherwise, the original global
variables are retained (e.g., all the functions defined in pool.R).
Assuming no new globals are defined by jobs, which they should not
be, this choice should be safe.

In this commit, I've benchmarked the change:

 +------------------+---------------+-------------+-------------+
 | benchmark        | globals=FALSE | msgpack     | v0          |
 +------------------+---------------+-------------+-------------+
 | cZeroBaseline    |   54.1 ± 1.5  |   53 ± 1.6  |   44 ± 4.5  |
 | pZeroBaseline    |   96.8 ± 3.5  |   94 ± 3.2  |   82 ± 4.0  |
 | pZeroFromForeign |  100.2 ± 1.4  |   99 ± 1.5  |   89 ± 6.7  |
 | pZeroToForeign   |  101.3 ± 3.2  |   98 ± 2.7  |   90 ± 5.7  |
 | rZeroBaseline    |  580.1 ± 6.2  |  678 ± 8.1  |  312 ± 5.5  |
 | rZeroFromForeign |  568.6 ± 3.2  |  672 ± 5.1  |  345 ± 11.9 |
 | rZeroToForeign   |  571.4 ± 4.5  |  660 ± 3.3  |  335 ± 6.6  |
 +------------------+---------------+-------------+-------------+
 | cTenBaseline     |   79.7 ± 3.2  |   79 ± 1.8  |   98 ± 5.7  |
 | pTenBaseline     |  126.3 ± 4.1  |  125 ± 3.2  |  133 ± 4.9  |
 | pTenFromForeign  |  706.5 ± 172  |  809 ± 160  | 2232 ± 49   |
 | pTenToForeign    |  509.0 ± 3.5  |  495 ± 3.9  | 2041 ± 44   |
 | rTenBaseline     | 1266.8 ± 2.9  | 1356 ± 9.2  | 1099 ± 34   |
 | rTenFromForeign  | 1333.8 ± 122  | 1527 ± 125  | 4191 ± 418  |
 | rTenToForeign    | 1538.6 ± 4.8  | 1646 ± 22   | 3529 ± 144  |
 +------------------+---------------+-------------+-------------+
 | rMarginalCost1   |  581.7 ± 7.0  |  680 ± 4.9  |  328 ± 7.9  |
 | rMarginalCost2   |  621.9 ± 2.9  |  774 ± 6.6  |  637 ± 22   |
 | rMarginalCost3   |  668.7 ± 18.5 |  863 ± 5.7  |  931 ± 55   |
 | rMarginalCost4   |  737.9 ± 12.1 | 1050 ± 2.7  | 1221 ± 38   |
 | pMarginalCost1   |  108.0 ± 0.9  |  107 ± 0.9  |   88 ± 4.4  |
 | pMarginalCost2   |  114.9 ± 1.4  |  114 ± 1.7  |  124 ± 4.1  |
 | pMarginalCost3   |  119.2 ± 1.7  |  117 ± 1.9  |  166 ± 4.9  |
 | pMarginalCost4   |  122.4 ± 0.7  |  120 ± 0.7  |  214 ± 11   |
 +------------------+---------------+-------------+-------------+
 | pMap1000         |  2.7          | 2.68 ± 0.04 | 47.0 ± 5.1  |
 | rMap1000         | 23.8          | 70.0        | -           |
 +------------------+---------------+-------------+-------------+
  • Loading branch information
arendsee committed Nov 10, 2024
1 parent 29f20cb commit 00c92d0
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 24 deletions.
2 changes: 2 additions & 0 deletions test-suite/executable-benchmark/serial-interop/foo.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ rid <- function(x) x
nmb <- function(n){
stringi::stri_dup("x", n * 1024 * 1024)
}

incr <- function(x, y) x + y
27 changes: 12 additions & 15 deletions test-suite/executable-benchmark/serial-interop/foo.loc
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,19 @@ module foo
, pMarginalCost2
, pMarginalCost3
, pMarginalCost4
, mapManyPC
, mapManyPCP
, mapManyPCR
)

import types (Real, List)
import types (List, Str, Int)
import cppbase (map)
import pybase (add)

source py from "foo.py" ("nmb" as pnmb, "pid", "len" as plen)
source R from "foo.R" ("nmb" as rnmb, "rid", "nchar" as rlen)
source py from "foo.py" ("nmb" as pnmb, "pid", "len" as plen, "addp")
source R from "foo.R" ("nmb" as rnmb, "rid", "nchar" as rlen, "addr")
source Cpp from "foo.hpp" ("nmb" as cnmb, "cid", "strlen" as clen)

type R => Str = "character"
type R => Int = "integer"

type Py => Str = "str"
type Py => Int = "int"

type Cpp => Str = "std::string"
type Cpp => Int = "int"
addp :: Int -> Int -> Int
addr :: Int -> Int -> Int

-- Generate a test string with a length of n megabytes
pnmb :: Int -> Str
Expand Down Expand Up @@ -94,5 +88,8 @@ pMarginalCost2 = (pid . cid . pnmb) 0
pMarginalCost3 = (pid . cid . pid . cid . pnmb) 0
pMarginalCost4 = (pid . cid . pid . cid . pid . cid . pnmb) 0

mapManyPC :: Real -> [Real] -> [Real]
mapManyPC x xs = map (add x) xs
mapManyPCP :: Int -> [Int] -> [Int]
mapManyPCP x xs = map (addp x) xs

mapManyPCR :: Int -> [Int] -> [Int]
mapManyPCR x xs = map (addr x) xs
3 changes: 3 additions & 0 deletions test-suite/executable-benchmark/serial-interop/foo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ def nmb(n):

def pid(x):
return x

def addp(x, y):
return x + y
26 changes: 17 additions & 9 deletions test-suite/executable-benchmark/serial-interop/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

set -e

morloc make foo.loc
# morloc make foo.loc
#
# # warmup
# hyperfine \
# -w 10 \
# -L test pTenBaseline,rTenBaseline,cTenBaseline \
# "./nexus.py {test}"
#
# hyperfine \
# -w 5 \
# -L test cZeroBaseline,pZeroBaseline,pZeroFromForeign,pZeroToForeign,rZeroBaseline,rZeroFromForeign,rZeroToForeign,cTenBaseline,pTenBaseline,pTenFromForeign,pTenToForeign,rTenBaseline,rTenFromForeign,rTenToForeign,rMarginalCost1,rMarginalCost2,rMarginalCost3,rMarginalCost4,pMarginalCost1,pMarginalCost2,pMarginalCost3,pMarginalCost4 \
# --export-markdown stats.markdown \
# --export-csv stats.csv \
# "./nexus.py {test}"
#
# hyperfine -w 5 -L test mapManyPCP,mapManyPCR "./nexus.py {test} 5 long-list.json"

hyperfine \
-w 5 \
-L test pZeroBaseline,rZeroBaseline,cZeroBaseline,pTenBaseline,rTenBaseline,cTenBaseline,pZeroToForeign,pZeroFromForeign,rZeroToForeign,rZeroFromForeign,pTenToForeign,pTenFromForeign,rTenToForeign,rTenFromForeign,rMarginalCost1,rMarginalCost2,rMarginalCost3,rMarginalCost4,pMarginalCost1,pMarginalCost2,pMarginalCost3,pMarginalCost4 \
--export-markdown stats.markdown \
--export-csv stats.csv \
"./nexus.py {test}"

hyperfine -w 5 "./nexus.py mapManyPC 5 long-list.json"
hyperfine -w 5 -L test mapManyPCR "./nexus.py {test} 5 long-list.json"

0 comments on commit 00c92d0

Please sign in to comment.