ra.png

Code For Ra Timing Tests With Varying Loop Counts

To Ra homepage
# time-jit-full.R

library(jit)

GCTORTURE.FLAG <- 0
TRACE.FLAG <- 0
QUICK.FLAG <- FALSE        # FALSE for full test, TRUE for quick test
N.OUTER.REPEATS <- 5       # for measuring time stddev
if (QUICK.FLAG == 1)
    N.OUTER.REPEATS <- 1

JIT.FLAG <- 1
source("time-jit-full-lib.R")

if (is.ra) {
    JIT.FLAG <- 2
    source("time-jit-full-lib.R")
}

# time-jit-full-lib.R

jit.flag <- 0
gctorture(GCTORTURE.FLAG)

test <- function(f, nrepeats)
{
    # na.rm=TRUE is useful when building the framework with very short times
    percent.relative.sd <- function(x) 100 * sd(x, na.rm=TRUE) / mean(x)

    time.jit <- time.nojit <- double(N.OUTER.REPEATS)

    nrepeats <- as.integer(nrepeats)  # use an integer index in for loops
    if (nrepeats == 0)
        nrepeats <- 1L

    cat(sprintf("%-32.32s %8.0f ", paste(substitute(f)), nrepeats))
    cat(sprintf("%6.0f  ", N))

    for (i in 1:N.OUTER.REPEATS) {
        if (i %/% 2) { # alternate test order, probably unnecessary
            if (is.ra) {
                jit.flag <<- JIT.FLAG;
                time.jit[i]   <- system.time(jit.result   <- f(nrepeats))[3]
            }
            jit.flag <<- 0;
            time.nojit[i] <- system.time(nojit.result <- f(nrepeats))[3]
        } else {
            jit.flag <<- 0;
            time.nojit[i] <- system.time(nojit.result <- f(nrepeats))[3]
            if (is.ra) {
                jit.flag <<- JIT.FLAG;
                time.jit[i]   <- system.time(jit.result   <- f(nrepeats))[3]
            }
        }
    }
    cat(sprintf(
        "%13.2f %5.1f     ",
        1e6 * mean(time.nojit) / nrepeats,      # time in us
        percent.relative.sd(time.nojit)))

    if (is.ra)
        cat(sprintf("%9.2f %5.1f  %6.3f %5.1f %7.3f",
            1e6 * mean(time.jit) / nrepeats,        # jittime in us
            percent.relative.sd(time.nojit),
            mean(time.jit / time.nojit),            # reltime
            percent.relative.sd(time.jit / time.nojit),
            mean(time.jit)))                        # jittot in secs

    cat("\n")

    if (is.ra)
        stopifnot(identical(nojit.result, jit.result))
}
convolve.jit <- function(N) # from the extending R manual
{
    jit(JIT.FLAG, TRACE.FLAG)
    a <- double(N)
    b <- double(N)
    na <- length(a)
    nb <- length(b)
    ab <- double(na + nb)
    for(i in 1:na)
        for(j in 1:nb)
             ab[i + j] <- ab[i + j] + a[i] * b[j]
    ab
}
convolve.nojit<- function(N) # from the extending R manual
{
    a <- double(N)
    b <- double(N)
    na <- length(a)
    nb <- length(b)
    ab <- double(na + nb)
    for(i in 1:na)
        for(j in 1:nb)
             ab[i + j] <- ab[i + j] + a[i] * b[j]
    ab
}
`convolve` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            convolve.jit(N)
    else
        for (i in 1:nrepeats)
            convolve.nojit(N)
}
looped.dnorm.jit <- function()
{
    jit(JIT.FLAG, TRACE.FLAG)
    mu <- 0
    sigma <- 1
    x <- 0
    for (i in 1:N) # from one of Luke's compiler documents
        x <- x + (1/sqrt(2 * pi)) * exp(-0.5 * ((x - mu)/sigma)^2) / sigma
    x
}
looped.dnorm.nojit<- function()
{
    mu <- 0
    sigma <- 1
    x <- 0
    for (i in 1:N) # from one of Luke's compiler documents
        x <- x + (1/sqrt(2 * pi)) * exp(-0.5 * ((x - mu)/sigma)^2) / sigma
    x
}
looped.dnorm <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
       for (i in 1:nrepeats)
           looped.dnorm.jit()
    else
       for (i in 1:nrepeats)
           looped.dnorm.nojit()
}
# use complex nbrs so nothing is jitted
# it's a way of measuring jit compilation overhead
while.complex.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    i <- 0i
    Ni <- N + 0i
    while (i != Ni)
        i <- i + 1
    i
}
while.complex.nojit <- function(N)
{
    i <- 0i
    Ni <- N + 0i
    while (i != Ni)
        i <- i + 1
    i
}
`while.complex` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
           while.complex.jit(N)
    else
        for (i in 1:nrepeats)
           while.complex.nojit(N)
    NULL
}
# Tests from Vadim Ogranovich post.
# See http://tolstoy.newcastle.edu.au/R/devel/05/04/0678.html
# Expressions are the same as Luke's email reply except
# that x and iA are local.

vadim1.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N); x <- double(N)
    for (i in iA)
        1
    x
}
vadim1.nojit <- function(N)
{
    iA <- seq(2,N); x <- double(N)
    for (i in iA)
        1
    x
}
`vadim1 1` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim1.jit(N)
    else
        for (i in 1:nrepeats)
            vadim1.nojit(N)
}
vadim2.jit <- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N)
    for (i in iA)
        i
    i
}
vadim2.nojit <- function(N)
{
    iA <- seq(2,N)
    for (i in iA)
        i
    i
}
`vadim2 i` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim2.jit(N)
    else
        for (i in 1:nrepeats)
            vadim2.nojit(N)
}
`vadim3.jit` <- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N)
    for (i in iA)
        i-1
    i
}
vadim3.nojit <- function(N)
{
    iA <- seq(2,N)
    for (i in iA)
        i-1
    i
}
`vadim3 i-1` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim3.jit(N)
    else
        for (i in 1:nrepeats)
            vadim3.nojit(N)
}
vadim4.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i-1]
    x
}
vadim4.nojit <- function(N)
{
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i-1]
    x
}
`vadim4 x[i-1]` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim4.jit(N)
    else
        for (i in 1:nrepeats)
            vadim4.nojit(N)
}
add1.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    x <- 0
    for(i in 1:N)
        x <- x+1
    x
}
add1.nojit <- function(N)
{
    x <- 0
    for(i in 1:N)
        x <- x+1
    x
}
`add1   x <- x + 1` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
           add1.jit(N)
    else
        for (i in 1:nrepeats)
           add1.nojit(N)
}
vadim5.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i] <- 1.0
    x
}
vadim5.nojit <- function(N)
{
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i] <- 1.0
    x
}
`vadim5 x[i] <- 1.0` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim5.jit(N)
    else
        for (i in 1:nrepeats)
            vadim5.nojit(N)
}
vadim6.jit<- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i] <- x[i-1]
    x
}
vadim6.nojit <- function(N)
{
    iA <- seq(2,N); x <- double(N); x[1] <- 1; x[2] <- 2
    for (i in iA)
        x[i] <- x[i-1]
    x
}
`vadim6 x[i] <- x[i-1]` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            vadim6.jit(N)
    else
        for (i in 1:nrepeats)
            vadim6.nojit(N)
}
# "frame" funcs are for estimating test and other framework overhead
frame1.jit <- function(N)
{
    jit(JIT.FLAG, TRACE.FLAG)
    for (i in 1:N)
       1
    1
}
frame1.nojit <- function(N)
{
    for (i in 1:N)
       1
    1
}
`frame1 for (i in 1:N) 1` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            frame1.jit(N)
    else
        for (i in 1:nrepeats)
            frame1.nojit(N)
}
frame2.jit<- function()
{
    jit(JIT.FLAG, TRACE.FLAG)
    0
}
frame2.nojit <- function()
{
    0
}
`frame2 0` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            frame2.jit()
    else
        for (i in 1:nrepeats)
            frame2.nojit()
}
frame3.jit<- function()
{
    jit(JIT.FLAG, TRACE.FLAG)
    0
}
frame3.nojit <- function()
{
    jit(0, TRACE.FLAG)
    0
}
`frame3 jit(0|1, TRACE.FLAG) 0` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    if (jit.flag)
        for (i in 1:nrepeats)
            frame3.jit()
    else
        for (i in 1:nrepeats)
            frame3.nojit()
}
frame4.none<- function()
{
}
`frame4 for (i in 1:nreps) null()` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    for (i in 1:nrepeats)
        frame4.none()
}
frame5.none<- function()
{
    mu <- 0
    sigma <- 1
    x <- 0
    (1/sqrt(2 * pi)) * exp(-0.5 * ((x - mu)/sigma)^2) / sigma
}
`frame5 dnorm no call to jit` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    for (i in 1:nrepeats)
        frame5.none()
}
frame6a <- function(N)
{
    jit(jit.flag, TRACE.FLAG)
    for (i in 1:N)
       1
    1
}
`frame6 for (i in 1:N) 1` <- function(nrepeats)
{
    if (nrepeats < 1)
        nrepeats <- 1
    for (i in 1:nrepeats)
        frame6a(N)
}
test.all <- function(N)
{
    test(`convolve`,              nrepeats / (5 * N))
    test(looped.dnorm, if (QUICK.FLAG) 30 else (10 * nrepeats) / N)
    test(`while.complex`,         (100 * nrepeats) / N)
    cat("\n")
    test(`vadim1 1`,              nrepeats / 2)
    test(`vadim2 i`,              nrepeats / 2)
    test(`vadim3 i-1`,            nrepeats / 2)
    cat("\n")
    test(`vadim4 x[i-1]`,         nrepeats / 2)
    test(`add1   x <- x + 1`,     nrepeats / 2)
    test(`vadim5 x[i] <- 1.0`,    nrepeats / 2)
    test(`vadim6 x[i] <- x[i-1]`, nrepeats / 2)
    cat("\n")
    test(`frame1 for (i in 1:N) 1`,          (100 * nrepeats) / N)
    test(`frame2 0`,                         (100 * nrepeats) / N)
    test(`frame3 jit(0|1, TRACE.FLAG) 0`,    (100 * nrepeats) / N)
    cat("\n")
    test(`frame4 for (i in 1:nreps) null()`, (100 * nrepeats) / N)
    test(`frame5 dnorm no call to jit`,      (100 * nrepeats) / N)
    test(`frame6 for (i in 1:N) 1`,          (100 * nrepeats) / N)
    cat("--------------------------------------------------------")
    cat("-------------------------------------------------------\n")
}

# We adjust nrepeats below so each jitted test takes roughly the same time.
# Loop counts are chosen so the jittot times are greater
# than about a second (with Ra version 5 on a 3G Pentium).

cat("is.ra", is.ra, "N.OUTER.REPEATS", N.OUTER.REPEATS, "QUICK.FLAG", QUICK.FLAG, "JIT.FLAG", JIT.FLAG, "\n\n")
cat("testname                         nrepeats      N           ")
cat("time   rsd       jittime   rsd reltime   rsd  jittot\n")

cat("                                                           ")
cat("  us     %            us     %             %    secs\n\n")

N <- 10L
nrepeats <- (if (QUICK.FLAG) 2e3 else 2e6) / N
test.all(N)

N <- 30L
nrepeats <- (if (QUICK.FLAG) 2e3 else 2e7) / N
test.all(N)

N <- 100L
nrepeats <- (if (QUICK.FLAG) 2e3 else 2e7) / N
test.all(N)

N <- 300L
nrepeats <- (if (QUICK.FLAG) 2e3 else 2e7) / N
test.all(N)

# N <- 1000L
# nrepeats <- (if (QUICK.FLAG) 2e3 else 2e7) / N
# test.all(N)

# N <- 10000L
# nrepeats <- (if (QUICK.FLAG) 2e3 else 2e7) / N
# test.all(N)

To Ra homepage