Ответ 1
В качестве короткого ответа вам необходимо проверить, в какой библиотеке BLAS связан ваш R.
- Если он связан с ссылкой BLAS, то, конечно, нет ответа;
- Если он связан с оптимизированным BLAS, ответ, возможно, да. Я использовал "возможно", потому что пример операции, которую вы даете: element wise product, не сопоставляется с процедурой BLAS. Он может быть просто закодирован как простой цикл C.
Однако, я считаю, что когда вы ссылаетесь на SIMD, вы имеете в виду более общее использование векторизации SIMD в R. Итак, давайте сначала немного узнаем о реализации SIMD, а затем переходим к R.
SIMD
В моих ограниченных знаниях есть только пять способов реализации SIMD (и у меня есть только практический опыт в первых двух):
- запись непосредственно архитектуры; Например, на архитектурах x86 мы можем использовать инструкции SSE/AVX;
- с использованием специфических для архитектуры векторных свойств; например, на архитектурах intel x86, мы можем использовать intel SSE/AVX intrinsics; Это более простой вариант, чем сборка, потому что внутренними являются макросы C, поэтому программисты все еще кодируют в среде C;
- с помощью векторных расширений для компилятора. Некоторые компиляторы будут определять свой собственный векторный тип данных, например, векторные расширения GCC можно найти здесь. Использование определенных векторных типов компилятора имеет одно потенциальное преимущество: вам не нужно беспокоиться о проблемах архитектуры. Компилятор скомпилирует ваш векторный код в совместимую сборку на этом компьютере;
- с помощью автоматической прорисовки для компилятора. Например, для GCC мы можем попробовать флаг
-ftree-vectorize
; - используя OpenMP pragma:
#pragma opm simd
.
В заключение
- вариант 1 требует записи значительного количества кода сборки;
- вариант 2 и вариант 3 требуют некоторой перекодировки вашего скалярного кода C, путем ручного разворачивания цикла и векторизации вручную;
- вариант 3 и вариант 4 не требуют изменения вашего скалярного кода на C; вы просто добавляете флаг компиляции или вставляете какую-то прагму компилятора.
Опции 1-3 обычно не переносятся: вам нужно изменить свой код при использовании другой архитектуры или другого компилятора. Опции 4-5 могут быть наименее ограниченными, но, как уже можно было предположить, они часто не дают оптимальной производительности по сравнению с вариантами 1-3, поскольку они полностью зависят от возможностей компилятора для векторизации.
Основная библиотека R: libR
Примитивные/внутренние функции (.Primitive()
, .Internal()
) в R, скомпилированы в эту библиотеку. Фундаментальные пакеты R, такие как base
, stats
, utils
, связаны с этой библиотекой. Эта библиотека должна быть загружена при вызове R. Теперь, поскольку R необходимо достичь переносимости на разных архитектурах, ядро R/ядро должно быть написано простым, переносимым C-кодом. В результате сам libR
не содержит SIMD, предлагаемого опциями 1-3.
У него также нет опции 4. R не имеет встроенного флага SIMD. У меня есть проверка на RHOME/etc/Makeconf
(я использую linux, поэтому не уверен, что он называется файлом конфигурации make в окнах), то вы увидите, что для SIMD-управления нет доступного флага компиляции.
Вариант 5 интересен. R имеет флаг OpenMP, но я убежден, что ядро R не использует какой-либо parallelism, включая SIMD. Я говорю "интересно", потому что сам не уверен, что этот флаг OpenMP позволяет писателям R писать код параллельного кода SIMD. Если кто-нибудь поможет мне прояснить этот момент, я буду очень благодарен.
Поддержка SIMD от libR
не подразумевает поддержки SIMD для R. Позвольте проверить библиотеку BLAS.
Библиотека BLAS
Загрузка только libR
недостаточна для выполнения R. Многие символы/функции в libR
являются внешними: т.е. они используются в libR
, но не определены в libR
. R называет их интерфейсом иностранного языка. Важным набором таких символов является BLAS (основные подпрограммы линейной алгебры). Процедуры BLAS уровня 1-3 выполняют соответственно:
- векторно-векторные операции (например, точечный продукт);
- операции с матричным вектором (например, умножение матричного вектора);
- операции матричной матрицы (например, матричное умножение и кросс-произведение)
и они лежат в центре научных вычислений. Например, оператор/функция R %*%
для матричного умножения, наконец, будет ссылаться на символ _dgemm
в libR
. Хотя он не определен в libR
, libR
связан с какой-либо библиотекой BLAS, где он определен. Когда загружается libR
, эта библиотека BLAS также загружается.
Разделение библиотеки libR
и BLAS, хотя по многим причинам приведено в R установка и администрирование - общий BLAS, подразумевается:
libR
лежит на уровне приложения и переносится, в то время как BLAS лежит на уровне вычислений и может быть настроен на архитектуру, что позволяет нам улучшить производительность R без восстановления R.
Существует два типа BLAS: эталонный BLAS и оптимизированный BLAS.
- Ссылка BLAS ничего особенного. Он закодирован в тривиальном гнезде цикла в F77; их легко перекодировать на C без потери производительности. Он статический, не развивающийся. Его название "ссылка" исходит из стандартного дизайна. Например, стандартным стандартом для матрично-матричного умножения является операция
dgemm: C <- beta * C + alpha * op(A) * op(B)
. - Оптимизированный BLAS постоянно развивается , ориентируясь на высокопроизводительные вычисления на различных основных архитектурах. Его дизайн очень сложный, с большим количеством рукописной сборки, предназначенной для разных архитектур. Оптимизированные библиотеки BLAS, либо ATLAS, OpenBLAS, либо Intel MKL кодируются с помощью оптимизации кеширования и векторизации SIMD, поэтому их вычисление может быть намного быстрее, чем использование ссылочного BLAS.
Загрузка BLAS в R
Когда R запущен, он будет искать несколько путей библиотеки для доступной библиотеки BLAS. Здесь есть принцип "первым пришел, первым служит".
- Верхний приоритет
libRblas
в каталогеRHOME/lib
. Это также каталог, гдеlibR
. Если этотlibRblas
существует, это означает, что при времени установки R он не обнаружил доступную библиотеку BLAS на машине, поэтому он создал свою собственную копию. Обычно эта копия является ссылкой BLAS. Тем не менее, мне недавно сказали, что на Mac (извините, я не использую Mac), двоичная версия R строит другую версию, используя OSXvecLIB
BLAS. Этот R для Mac часто задает вопрос. Но по умолчанию R не привязан к этой оптимизированной версии; в FAQ дается подробная информация о том, как сделать псевдоним для загрузки оптимизированной библиотеки BLAS. - Теперь, если
libRblas
не существует, то это означает, что существующая библиотека BLAS была обнаружена в момент времени R, и R был автоматически связан с ней. Теперь это будет более тонким в этом случае. Мы должны сначала проверить, с какой библиотекой BLAS R связаны с:R CMD config BLAS_LIBS
. На моем ноутбуке (работает ubuntu 14.04.3) я получаю-lblas
. Это означает, что он связан сlibblas
, эталонным BLAS (единственным BLAS, который у меня был, когда я установил R). Теперь, если мы хотим связать R с другой версией BLAS, скажем OpenBLAS, мы должны сделать псевдонимlibblas
. Обратите внимание, что если есть несколько версий BLAS при времени установки R, к которым BLAS R будет ссылаться, возможно, менее предсказуем. В некоторых ситуациях на некоторых платформах Intel R может быть привязан к эталонному BLAS, даже если есть существующий Intel MKL. Это можно проверить, используя приведенный вышеR CMD config BLAS_LIBS
.
В приведенном выше документе я подробно рассказал о том, как BLAS находится по R, и как мы можем загружать в R с разницей BLAS путем сглаживания. Но настройка псевдонимов библиотек требует доступа root/Administrative. Недавно у меня была запись: без root-доступа: как запустить R с Tunded BLAS, когда R связано со ссылкой BLAS, которая предлагает некоторые решения на платформе Linux.