我正在尝试让我的代码在我的GPU上运行,而不是CPU - 好吧,它正在运行,但不是很好。让我给出代码的相关部分:
u = zeros(n*L,1 ,'gpuArray'); ubar = zeros(n*L,1 ,'gpuArray');
y = zeros(n*L*d,1,'gpuArray'); ybar = zeros(n*L*d,1,'gpuArray');
v = zeros(n*L*d,1,'gpuArray');
w = zeros(n,1 ,'gpuArray');
z = zeros(n*L*d,1,'gpuArray');
...
v_arg = v + sigma * (D * ubar - T_t * ybar); (1)
w_arg = w + sigma * Q * ubar;
z_arg = z + sigma * ybar;
v_new = back.dual.v(v_arg,w_arg,z_arg);
w_new = back.dual.w(v_arg,w_arg,z_arg);
z_new = back.dual.z(v_arg,w_arg,z_arg);
u_arg = u - tau * (D_t * v_new + Q_t * w_new); (2)
y_arg = y - tau * (z_new - T * v_new);
u_new = back.prim.u(u_arg,y_arg);
y_new = back.prim.y(u_arg,y_arg);
ubar_new = u_new + theta*(u_new - u);
ybar_new = y_new + theta*(y_new - y);
...
% The dimensions of the matrices are as follows:
% D is (n*L*d,n*L); T is (n*L*d,n*L*d); Q is (n,n*L).
% Finally, "_t" denotes the transpose of a matrix. I found that it is a lot
% faster to define a new matrix that is the transpose, instead of doing the
% transpose operation each time.
两个标记的等式 - (1)和(2) - 是瓶颈。有关我的一次跑步所用的时间,请参见下图。 see the relevant MSDN documentation for details
最后,矩阵是稀疏矩阵 - 我正在使用Matlab 2015a,因此GPU上的稀疏矩阵很好(2014b不喜欢它们)。参数的特征尺寸如下:n = 60^2 = 3600, L = 48, d = 2
。
以下是CPU的相应时间。请注意,所调用的次数是接近的20倍,这就是为什么有些时间实际上更长。
有趣的是,我认为,在比较CPU和GPU时,不同线路的效率会有所不同。最后一行在GPU上略快,但倒数第二行在GPU上慢了大约6倍,第一行在GPU上慢了大约20倍。
如果需要更多信息,请告知我们。
以下是MVCE:
N = [50,50];
n = prod(N); d = numel(N);
L = 64;
sigma = 0.1;
tau = 0.1;
D = spdiags([-ones(n*L*d,1), ones(n*L*d,1)],0:1,n*L*d,n*L);
D_t = D';
T = spdiags([-ones(L*d,1), ones(L*d,1)],0:1,L*d,L*d);
T = kron(T,speye(n));
T_t = T';
Q = sparse(n,n*L);
for j = 1:L
Q(:,1+(j-1)*n:j*n) = speye(n); %#ok<SPRIX>
end
Q_t = Q';
u = zeros(n*L,1 ,'gpuArray');
y = zeros(n*L*d,1,'gpuArray');
v = zeros(n*L*d,1,'gpuArray');
w = zeros(n,1 ,'gpuArray');
z = zeros(n*L*d,1,'gpuArray');
count = 0;
count_max = 1000; % Choose count_max as the maximum number of iterations
while count <= count_max
v = v + sigma * (D * u - T_t * y);
w = w + sigma * Q * u;
z = z + sigma * y;
u = u - tau * (D_t * v + Q_t * w);
y = y - tau * (z - T * v);
count = count + 1;
if mod(count,10) == 0
fprintf('count = %1g\n',count)
end
end
答案 0 :(得分:1)
解决!问题在于,当我将矩阵分配给GPU时,我正在定义一个新的矩阵D_t
作为转置 - 这是因为我没有必要在GPU上进行矩阵的转置每次都节省了大量的时间 - 我没有将转置矩阵分配给GPU!
正如rayryeng指出的那样,道德是确保你的所有数组都是gpuArray
!希望我的错误会阻止其他人犯同样的错误! :)