Можно ли и как ускорить работу Octave с помощью CUDA? Нет ничего проще!

Без бенчмарки не оценить прирост в скорости. Бенчмарка честно утащена отсюда.

N = 16384;
A = single(rand(N,N));
B = single(rand(N,N));
start = clock();
C = A * B;
elapsedTime = etime(clock(), start);
disp(elapsedTime);
gFlops = 2*N*N*N/(elapsedTime * 1e+9);
disp(gFlops);

Как есть на 2 x E5-2697v2 QS.

$ octave bench.m
 15.909
 552.90

500 гигафлопс. 16 секунд.

Настройка

Должны быть все зависимости включая cublas и nvblas. Обычно они сразу есть с CUDA.

$ aptitude search ~iblas
i A libblas-common   - Dependency package for all BLAS implementations 
i A libblas3         - Basic Linear Algebra Reference implementations, shared library
i A libcublas8.0     - NVIDIA cuBLAS Library    
i A libnvblas8.0     - NVBLAS runtime library
i A libopenblas-base - Optimized BLAS (linear algebra) library (shared library)

NVBLAS просит конфиг.

tee ~/.config/nvblas.conf <<EOF
NVBLAS_CPU_BLAS_LIB $(dpkg -L libopenblas-base | grep libblas)
NVBLAS_GPU_LIST ALL
EOF

Может иметь смысл опустить последнюю строчку. Мы проверим ниже.

Чтобы каждый раз не настраивать, укажем необходимое в обёртке для Octave.

tee ~/bin/octave-gpu <<EOF
#!/bin/bash
export NVBLAS_CONFIG_FILE=~/.config/nvblas.conf
export LD_PRELOAD=libnvblas.so
/usr/bin/octave "\$@"
EOF
chmod +x ~/bin/octave-gpu

Проверка

И ещё раз посчитаем.

$ octave-gpu bench.m 2>/dev/null
 8.7542
 1004.8

Один терафлопс и восемь секунд. Почти в два раза быстрее. И UPS не пищит обиженно от перегрузки!

В другой консоли в это же время можно видеть вырастающую утилизацию.

$ nvidia-smi dmon -d 5
# gpu   pwr  temp    sm   mem   enc   dec  mclk  pclk
# Idx     W     C     %     %     %     %   MHz   MHz
    0    10    40     0     0     0     0   405   139
    1    35    31     3     6     0     0   405   139
    0    55    41     0     0     0     0  4513  1417
    1    35    32     3     2     0     0  3504  1290
    0    55    42     0     0     0     0  4513  1417
    1    35    32     1     1     0     0  3504  1290

SLI

Для проверки прогоним то же на одной только карте.

$ CUDA_VISIBLE_DEVICES=0 octave-gpu bench.m 2>/dev/null
 14.233
 618.00
$ CUDA_VISIBLE_DEVICES=1 octave-gpu bench.m 2>/dev/null
 18.129
 485.19

Очевидно, от использования двух карт польза есть даже если разных классов. Также очевидно что даже старые многоядерные Xeon ещё рано списывать со счёта.

Итого

На такой относительно примитивной и ходовой задаче от GPU мы получаем приятный прирост скорости и меньше платим за электричество.

Теперь и при обычном использовании в Octave все сложные расчёты могут делаться на GPU. Другой вопрос что на небольших задачах вы можете не заметить прироста из-за затрат на копирование данных туда-cюда.

Дополнительное чтение