【发布时间】:2015-10-15 07:32:29
【问题描述】:
我目前正试图让我的代码在我的 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) - 是瓶颈。请参阅下图了解我的一次跑步的时间。 .
最后,矩阵是稀疏矩阵 - 我使用的是 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
【问题讨论】:
-
在衡量性能时,通常包括数据大小。在调用每一行之前,矩阵的大小是多少?这很重要。除非您向我们提供有关如何重建问题的更多信息,否则我们无法判断出什么问题。我们只有您的代码。您能否为每个变量提供样本输入,以便我们进一步评估您的问题?
-
糟糕,是的,忘记输入参数的大小了!我现在就更新。
-
您还需要什么? :)
-
是否可以为每个矩阵提供样本输入,以便您的示例是 MVCE? stackoverflow.com/help/mcve。如果我们能够真正重现您的结果以找出您的错误,那将会有所帮助。到目前为止,这两行的运行时间较大的原因可能是任何原因。
-
另外,您是否尝试过使用基于 CPU 的数组并运行计算并比较结果? CPU版本比GPU版本快还是慢?
标签: performance matlab gpu