Код ниже принимает 3 целых числа и создает большой блок данных. В более общем случае я хотел бы предоставить векторы q, p
значительных размеров, скажем, 5000, и создать большую матрицу данных (здесь это будет 17x15000
). Однако каждый block
должен быть вычислен путем выполнения последовательности матричных операций. Из исследования сети я обнаружил, что Matlab поддерживает только операции с массивами на графическом процессоре, и вычисления обычно включают крупномасштабные матрицы , а не маленькие матрицы, такие как 3x3
матрицы в пример ниже. Кроме того, код должен быть правильно векторизован. Матричная документация упоминает матричные операции в документации , однако она относится только к некоторым встроенным функциям.
Возможно ли поэтому выполнить мой код на GPU? Если я правильно понимаю, пользовательские функции (вызываемые с arrayfun
) могут включать только поэтапные операции. Есть ли другой способ?
Если, с другой стороны, это хороший случай для ускорения GPU, как я могу добиться этого с Matlab?
main script.m
fi = pi/2;
L = 0.4; mass = 0.5;
p = 0.5; pnext = 0.1;
sC1 = [-L/2; 0]; sC2 = [L/2; 0];
Icm = 1/12*mass*L^2; M = diag([mass mass Icm]);
input = struct('M',M,'sC1_loc',sC1,'sC2_loc',sC2);
% fill data
s = 1000;
GlobalAsm = zeros(17, 3 * s);
tic
for i = 1 : s
GlobalAsm(:,3*i-2:3*i) = createBlock2(0.5*i,i/2, i,input);
end
t2 = toc % t2 = 0.1 approx
createBlock.m
function block = createBlock(fi,p, pnext,input)
M = input.M; sC2_loc = input.sC2_loc;
sC1_loc = input.sC1_loc; s12_loc = sC1_loc-sC2_loc;
Om = [0, -1; 1, 0]; H = [0; 0; 1];
s12 = Rot(fi)*s12_loc; s21 = -Rot(fi)*s12_loc;
s1C = -Rot(fi)*sC1_loc; s2C = -Rot(fi)*sC2_loc;
S12 = eye(3); S21 = eye(3);
S1c = eye(3); S2c = eye(3);
S12(3,1:2) = (Om*s12).'; S21(3,1:2) = (Om*s21).';
S1c(3,1:2) = (Om*s1C).'; S2c(3,1:2) = (Om*s2C).';
M1 = S1c * M * S1c.'; M2 = S2c * M * S2c.';
KSI11 = inv(M1); KSI12 = M1 \ S12;
KSI22 = inv(M2); KSI21 = M2 \ S21;
KSI10 = M1 \ (+H*p - S12*H*pnext);
KSI20 = M2 \ (-H*pnext + S21*H*p);
block = [KSI11; KSI12; KSI21; KSI22; KSI10.'; KSI20.'; S12];
function R = Rot(fi)
R = [cos(fi) -sin(fi);
sin(fi) cos(fi)];
РЕДАКТИРОВАТЬ: Основываясь на приведенном ниже преобразовании, я хочу показать простой пример. Теперь в main
данные заполняются с помощью createBlock
. Все выполняется на процессоре, и для его завершения требуется около 0,1 с.
Ниже приведен тот же код с переменными gpuArray. Это займет значительно больше времени (около 11 секунд). Как мне переформулировать код, чтобы воспользоваться ускорением графического процессора?
main script on GPU
s = 1000;
GlobalAsm = zeros(17, 3 * s, 'gpuArray');
tic
for i = 1 : s
i = gpuArray(i);
GlobalAsm(:,3*i-2:3*i) = createBlock2(0.5*i,i/2, i,input);
end
t = toc % t = 11.0s approx
createBlock2.m on GPU
function block = createBlock2(fi,p, pnext,input)
M = input.M; sC2_loc = input.sC2_loc;
sC1_loc = input.sC1_loc; s12_loc = sC1_loc-sC2_loc;
Om = gpuArray([0, -1; 1, 0]); H = gpuArray([0; 0; 1]); % <- change in this line
s12 = Rot(fi)*s12_loc; s21 = -Rot(fi)*s12_loc;
s1C = -Rot(fi)*sC1_loc; s2C = -Rot(fi)*sC2_loc;
[S12, S21, S1c, S2c] = deal(gpuArray.eye(3)); % <- change in this line
S12(3,1:2) = (Om*s12).'; S21(3,1:2) = (Om*s21).';
S1c(3,1:2) = (Om*s1C).'; S2c(3,1:2) = (Om*s2C).';
M1 = S1c * M * S1c.'; M2 = S2c * M * S2c.';
KSI11 = inv(M1); KSI12 = M1 \ S12;
KSI22 = inv(M2); KSI21 = M2 \ S21;
KSI10 = M1 \ (+H*p - S12*H*pnext);
KSI20 = M2 \ (-H*pnext + S21*H*p);
block = [KSI11; KSI12; KSI21; KSI22; KSI10.'; KSI20.'; S12];
function R = Rot(fi)
R = [cos(fi) -sin(fi);
sin(fi) cos(fi)];