Производительность NumPy с различными реализациями BLAS

Я запускаю алгоритм, реализованный в Python, и использует NumPy. Самая вычислительная дорогостоящая часть алгоритма включает решение набора линейных систем (т.е. Вызов numpy.linalg.solve()). Я придумал этот небольшой тест:

import numpy as np
import time

# Create two large random matrices
a = np.random.randn(5000, 5000)
b = np.random.randn(5000, 5000)

t1 = time.time()
# That the expensive call:
np.linalg.solve(a, b)
print time.time() - t1

Я запускаю это:

  • Мой ноутбук, конец 2013 года MacBook Pro 15 "с 4 ядрами на 2 ГГц (sysctl -n machdep.cpu.brand_string дает мне процессор Intel (R) Core i7-4750HQ с частотой 2.00 ГГц)
  • экземпляр Amazon EC2 c3.xlarge с 4 vCPU. Amazon рекламирует их как "высокочастотные процессоры Intel Xeon E5-2680 v2 (Ivy Bridge)".

Нижняя строка:

  • На Mac он работает в ~ 4,5 секунды
  • В экземпляре EC2 он работает в ~ 19,5 секунд

Я попробовал это также на других установках OpenBLAS/Intel MKL, а время выполнения всегда сопоставимо с тем, что я получаю на экземпляре EC2 (по модулю конфигурации оборудования).

Может ли кто-нибудь объяснить, почему производительность Mac (с ускорением Framework) лучше на 4 раза? Подробнее о настройках NumPy/BLAS в каждом из них приведены ниже.

Настройка ноутбука

numpy.show_config() дает мне:

atlas_threads_info:
  NOT AVAILABLE
blas_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
    define_macros = [('NO_ATLAS_INFO', 3)]
atlas_blas_threads_info:
  NOT AVAILABLE
openblas_info:
  NOT AVAILABLE
lapack_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3']
    define_macros = [('NO_ATLAS_INFO', 3)]
atlas_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

Настройка экземпляра EC2:

В Ubuntu 14.04 я установил OpenBLAS с

sudo apt-get install libopenblas-base libopenblas-dev

При установке NumPy я создал site.cfg со следующим содержимым:

[default]
library_dirs= /usr/lib/openblas-base

[atlas]
atlas_libs = openblas

numpy.show_config() дает мне:

atlas_threads_info:
    libraries = ['lapack', 'openblas']
    library_dirs = ['/usr/lib']
    define_macros = [('ATLAS_INFO', '"\\"None\\""')]
    language = f77
    include_dirs = ['/usr/include/atlas']
blas_opt_info:
    libraries = ['openblas']
    library_dirs = ['/usr/lib']
    language = f77
openblas_info:
    libraries = ['openblas']
    library_dirs = ['/usr/lib']
    language = f77
lapack_opt_info:
    libraries = ['lapack', 'openblas']
    library_dirs = ['/usr/lib']
    define_macros = [('ATLAS_INFO', '"\\"None\\""')]
    language = f77
    include_dirs = ['/usr/include/atlas']
openblas_lapack_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

Ответ 1

Причиной такого поведения может быть то, что Accelerate использует многопоточность, а другие - нет.

Большинство реализаций BLAS следуют за переменной среды OMP_NUM_THREADS, чтобы определить, сколько потоков необходимо использовать. Я считаю, что они используют только один поток, если не указано иное явно. Ускорить man-страницу, однако по-прежнему включается потоковая передача; его можно отключить, установив переменную окружения VECLIB_MAXIMUM_THREADS.

Чтобы определить, действительно ли это происходит, попробуйте

export VECLIB_MAXIMUM_THREADS=1

перед вызовом версии Accelerate и

export OMP_NUM_THREADS=4

для других версий.

Независимо от того, действительно ли это причина, рекомендуется всегда устанавливать эти переменные при использовании BLAS, чтобы убедиться, что вы контролируете происходящее.