Скомпилированный код R на самом деле медленнее, чем чистый R с включенным JIT - PullRequest
0 голосов
/ 01 марта 2019

Из Эффективного R программирования байт-компилятора и R-документа r байтовый компилятор , я узнал, что cmpfun может использоваться для компиляции чистой R функции в байт-код дляspeed и enableJIT можно ускорить, включив just-in-time компиляцию.

Итак, я решил сделать тест, точно так же, как первая ссылка , используя следующий код:

library("compiler")
library("rbenchmark")

enableJIT(3)

my_mean = function(x) {
    total = 0
    n = length(x)
    for (each in x)
        total = total + each
    total / n
}

cmp_mean = cmpfun(my_mean, list(optimize = 3))

## Generate some data
x = rnorm(100000)
benchmark(my_mean(x), cmp_mean(x), mean(x), columns = c("test", "elapsed", "relative"), order = "relative", replications = 5000)

К сожалению, результат не тот, где показала первая ссылка .Производительность my_mean даже лучше, чем cmp_mean:

         test elapsed relative
3     mean(x)   1.468    1.000
1  my_mean(x)  35.402   24.116
2 cmp_mean(x)  36.817   25.080

Я не могу понять, что произошло.

Редактировать:

R версия на моем компьютере 3.5.2.

Операционная система debian 9.8.Все программное обеспечение на моем компьютере обновлено до стабильного источника, предоставленного debian.

linux версия ядра 4.9.0-8-amd64.

Eidt5:

Я переписал сценарии для проверки различных комбинаций optimize и JIT:

#!/usr/bin/env Rscript

library("compiler")
library("microbenchmark")
library("rlist")

my_mean = function(x) {
    total = 0
    n = length(x)
    for (each in x)
    total = total + each
    total / n
}

do_cmpfun = function(f, f_name, optimization_level) {
    cmp_f = cmpfun(f, list(optimize = optimization_level))
    list(cmp_f, f_name, optimize = optimization_level)
}

do_benchmark = function(f, f_name, optimization_level, JIT_level, x) {
    result = summary(microbenchmark(f(x), times = 1000, unit = "us", control = list(warmup = 100)))
    data.frame(fun = f_name, optimize = optimization_level, JIT = JIT_level, mean = result$mean)
}

means = list(list(mean, "mean", optimize = -1), list(my_mean, "my_mean", optimize = -1))

for (optimization_level in 0:3)
    means = list.append(means, do_cmpfun(my_mean, "my_mean", optimization_level))

# Generate some data
x = rnorm(100000)

# Benchmark in different JIT levels
result = c()
for (JIT_level in 0:3) {
    enableJIT(JIT_level)

    for (f in means) {
    result = rbind(result, do_benchmark(f[[1]], f[[2]], f[[3]], JIT_level, x))
    }
}


# Sort result
sorted_result = result[order(result$mean), ]
rownames(sorted_result) = NULL

print("Unit = us, optimize = -1 means it is not processed by cmpfun")
print(sorted_result)

Я запустил sudo cpupower frequency-set --governor performance перед запуском сценария R и получил это:

[1] "Unit = us, optimize = -1 means it is not processed by cmpfun"
       fun optimize JIT       mean
1     mean       -1   2   229.1841
2     mean       -1   1   229.3910
3     mean       -1   3   236.3680
4     mean       -1   0   252.9416
5  my_mean       -1   2  5242.0413
6  my_mean        3   0  5279.9710
7  my_mean        2   2  5297.5323
8  my_mean        2   1  5327.0324
9  my_mean       -1   1  5333.6941
10 my_mean        3   1  5336.4559
11 my_mean        2   0  5362.6644
12 my_mean        3   3  5410.1963
13 my_mean        2   3  5414.4616
14 my_mean       -1   3  5418.3823
15 my_mean        3   2  5437.3233
16 my_mean        1   2  9947.7897
17 my_mean        1   1 10101.6464
18 my_mean        1   3 10204.3253
19 my_mean        1   0 10323.0782
20 my_mean        0   0 26557.3808
21 my_mean        0   2 26728.5222
22 my_mean       -1   0 26901.4200
23 my_mean        0   3 26984.5200
24 my_mean        0   1 27060.6188

Однакопосле того, как я update-alternative d libblas.so.3 и liblapack.so.3 на тот, который предоставлен openblas 0.2.19-3, my_mean с optimize = 3 и JIT = 0 становится тем, который имеет лучшую производительность (исключая mean):

[1] "Unit = us, optimize = -1 means it is not processed by cmpfun"
       fun optimize JIT       mean
1     mean       -1   0   228.9361
2     mean       -1   1   229.1223
3     mean       -1   2   233.9757
4     mean       -1   3   241.7835
5  my_mean        3   0  5246.8089
6  my_mean       -1   1  5261.3951
7  my_mean       -1   2  5330.6310
8  my_mean        2   3  5362.2055
9  my_mean        3   1  5400.9983
10 my_mean        2   0  5418.7674
11 my_mean        2   1  5460.8133
12 my_mean        3   3  5464.8280
13 my_mean       -1   3  5520.7021
14 my_mean        2   2  5591.7352
15 my_mean        3   2  5610.6446
16 my_mean        1   3 10244.2832
17 my_mean        1   0 10274.7504
18 my_mean        1   1 10311.6423
19 my_mean        1   2 10735.6449
20 my_mean        0   2 26904.1858
21 my_mean       -1   0 26961.0536
22 my_mean        0   0 27115.8191
23 my_mean        0   3 27538.7224
24 my_mean        0   1 28133.6159

То же самое с mkl 2019.02-057:

[1] "Unit = us, optimize = -1 means it is not processed by cmpfun"
       fun optimize JIT       mean
1     mean       -1   1   257.8620
2     mean       -1   0   263.3743
3     mean       -1   2   280.6906
4     mean       -1   3   291.8409
5  my_mean        2   0  5445.3252
6  my_mean        2   2  5462.4575
7  my_mean        3   3  5560.2931
8  my_mean       -1   1  5591.0089
9  my_mean        3   1  5645.3897
10 my_mean        3   0  5676.1714
11 my_mean        3   2  5707.7964
12 my_mean        2   3  5757.7887
13 my_mean       -1   3  5856.0215
14 my_mean       -1   2  5897.1735
15 my_mean        2   1  6363.1090
16 my_mean        1   2  9973.7666
17 my_mean        1   1 10557.8154
18 my_mean        1   0 10926.6103
19 my_mean        1   3 16030.0326
20 my_mean        0   0 27461.4078
21 my_mean        0   1 27939.7680
22 my_mean       -1   0 27985.4590
23 my_mean        0   3 30394.2772
24 my_mean        0   2 33768.5701
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...