<- 10000
size <- matrix(rnorm(size**2), size, size)
mat
tic()
<- mat %*% mat
get_res toc()
Intel MKL & Open Blas
Nous allons d’abord installer les librairies Intel MKL (processeur Intel nécessaire) & Open Blas. Ces deux librairies d’algèbre linéaire permettent d’optimiser et/ou de paralléliser un certains nombre d’opérations algébriques, notamment le calcul matriciel.
Nous les testons avec un produit matriciel de 10000 x 10000.
Avant l’installation les librairies utilisées pour du calcul matriciel en R sont libblas.so.3.10.0
et liblapack.so.3.10.0
(on peut les voir avec la ligne suivante)
sessionInfo()
Installation sur Windows (seulement Intel MKL)
Le plus simple est de télécharger les librairies Intel - MKL sur le seafile d’Agroparistech.
1 - Faire une copie de la version actuelle de BLAS
et LAPACK
:
Dans le dossier C:\Program Files\R\Your_R_Version\bin\x64
, copier Rblas.dll
et Rlapack.dll
dans un autre dossier à conserver pour pouvoir revenir aux librairies de la base R
.
2 - Télécharger les librairies Intel-MKL
En allant sur https://seafile.agroparistech.fr/d/696def33ceb848508cb0/ et en cliquant sur le boutton vert ZIP
en haut à droite, vous pouvez télécharger le dossier. Puis le déziper.
3 - Copier les bibliothèques
Lorsque le dossier est décompressé, allez dans \Intel-MKL-Libs\Intel_MKL
et copiez tous les fichiers dans votre C:\Program Files\R\Your_R_Version\bin\x64
.
4 - Réouverture de R
Vous pouvez fermer votre session R
et la rouvrir. Maintenant votre session R
devrait fonctionner avec Intel-MKL
. Vérifiez si vous avez gagné en efficacité sur votre ordinateur. Attention, le code déjà parallélisé pourrait être moins efficace car ces bibliothèques parallélisent déjà l’algèbre linéaire.
Concrètement on remplace les deux fichiers faisant appel aux librairies BLAS
et LAPACK
par des fichiers du même nom mais qui en pratique font implicitement appel à mkl. Pensez bien à sauver une copie des fichiers initiaux.
Pour retourner à la base R
il suffit d’opérer à l’opération inverse, copie des fichiers Rblas.dll
, Rlapack.dll
et libiomp5md.dll
du dossier C:\Program Files\R\Your_R_Version\bin\x64
. Les mettre en sécurité puis copier les librairies des Rblas.dll
et Rlapack.dll
depuis votre sauvegarde ou https://seafile.agroparistech.fr/d/696def33ceb848508cb0/.
Installation sur Ubuntu 22.04 (Intel MKL et Open Blas)
Intel MKL
sudo apt install intel-mkl
Open Blas
sudo apt install libopenblas-base
Changement de librairie
Pour changer la librairie Blas
sudo update-alternatives --config libblas.so.3-x86_64-linux-gnu
Pour changer la librairie Lapack
sudo update-alternatives --config liblapack.so.3-x86_64-linux-gnu
Dans les deux cas cela ouvre un menu montrant les différentes librairies disponibles.
Comparaison produit matriciel (BLAS
)
Une fois installées, vérifier si les librairies sont bien référencées pour le calcul matriciel avec
sessionInfo()
tic()
<- mat %*% mat
get_res toc()
Système d’exploitation | Library | CPU | Base R | Intel MKL |
---|---|---|---|---|
Windows 10 | Intel MKL | Intel Xeon - 16 processeur logiques | 15 min | 7 secondes |
Ubuntu 22.04 | Intel MKL | Intel i7 - 8 processeur logiques | 5 min | Moins de 1 min |
Ubuntu 22.04 | Open Blas | Intel i7 - 8 processeur logiques | 5 min | 9-14 secondes |
Benchmark approfondi
Nous allons comparer les performances de toutes ces librairies sur Ubuntu avec un ordinateur à 8 cœurs Intel I7. Pour effectuer ce benchmark nous devons réitérer les fermetures de sessions donc le même code à été lancé séquentiellement.
Set-up
Packages
library(ggplot2)
library(purrr)
library(dplyr)
library(furrr)
library(future)
library(tictoc)
Fonctions de test
<- function(seed, type = 'type'){
test_type <- data.frame(seed = rep(0,2),
res time = rep(0,2),
type = rep(0,2),
matrix_size = rep(0,2))
<- c(200, 2000)
matrix_size for(j in 1:2){
set.seed(seed)
= matrix(rnorm(matrix_size[[j]] ^ 2), ncol = matrix_size[[j]])
mat = Sys.time()
T1 = mat %*% mat
res_tmp = Sys.time()
T2 $seed[[j]] <- seed
res$time[[j]] <- difftime(T2, T1)
res$type[[j]] <- type
res$matrix_size[[j]] <- matrix_size[[j]]
res
}return(res)
}
<- function(seeds,type = 'type'){
compare if(type == "base"){
plan(multisession, workers = availableCores())
future_map_dfr(seeds,~test_type(.x,type = type))
else{
}map_dfr(seeds,~test_type(.x,type = type))
}
}
<- function(data){
my_multiplot ggplot(data = data,
aes(x = time, y = type, fill = type,col = type)) +
geom_boxplot(alpha = 0.5,show.legend = F) +
facet_wrap("matrix_size",scales = "free_x",labeller = label_both)
}
Paramètres
<- c("base","openblas","lasy_intel_mkl","intel_mkl_high_perf")
types <- 1:20 seeds
Sélection de la librarie active
<- types[[1]] type
Calculs et sauvegarde
<- compare(seeds,type)
res
saveRDS(res, file = paste0('res_algebrica_calculations/res_',type,'.RDS'))
Chargement des résultats
<- grep("^res_algebrica_calculations/res_.*.RDS$",
list_of_results dir(recursive = T),
value=T)
<- map_dfr(list_of_results,readRDS) res_table
Graph des résultats complets
On peut voir dans ces graphiques que dans l’ensemble OpenBlas et Intel-MKL sont plus efficaces que la base de R. Cependant d’autres remarques sont à faire :
- OpenBlas est utilise constamment l’ensemble des cœurs disponibles, ce comportement extrême peu devenir un problème lors des longs calculs où lorsque l’on utilise des librairies plus complexes comme par exemple
Rcpp
avec laquelle il obtiens des performances largement plus faible que la base. - Nous avons aussi remarqué une certaine variations dans les performances de Intel-MKL sur Ubuntu seulement. Bien que toujours observée plus efficace que la base. Il est fréquent que pour un même calcul le temps soit jusqu’à 4 fois plus long que le minimum. Cette variation semble être fixe pour chaque session R ouverte. Dans ces graph nous appelons “lasy intel mkl” les sessions de faible performances.
my_multiplot(res_table)
Sans la base R
%>%
res_table filter(type != "base") %>%
my_multiplot()