Из Эффективного 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