我认为在Julia中(与R或Matlab不同),devectorized代码通常比矢量化代码更快。但我并没有发现这种情况。这是一个例子:
julia> x = Float64[1:10000000];
julia> y = Array(Float64, length(x));
julia> @time for i = 1:length(x) y[i] = exp(x[i]) end;
elapsed time: 7.014107314 seconds (959983704 bytes allocated, 25.39% gc time)
julia> @time y = exp(x);
elapsed time: 0.364695612 seconds (80000128 bytes allocated)
为什么矢量化代码要快得多?看起来像devectorized代码分配的内存超过10倍。但实际上只需要分配几个字节来取幂任意数量的浮点数。有没有办法编写devectorized代码,以便它不会分配如此多的内存,因此比矢量化代码运行得更快?
谢谢!
答案 0 :(得分:10)
请考虑以下代码段:
x = Float64[1:10000000];
y = Array(Float64, length(x));
function nonglobal_devec!(x,y)
for i = 1:length(x) y[i] = exp(x[i]) end
end
function nonglobal_vec(x)
exp(x)
end
@time nonglobal_devec!(x,y);
@time y = nonglobal_vec(x);
x = Float64[1:10000000];
y = Array(Float64, length(x));
@time for i = 1:length(x) y[i] = exp(x[i]) end
@time y = exp(x)
给出时间
A: elapsed time: 0.072701108 seconds (115508 bytes allocated)
B: elapsed time: 0.074584697 seconds (80201532 bytes allocated)
C: elapsed time: 2.029597656 seconds (959990464 bytes allocated, 22.86% gc time)
D: elapsed time: 0.058509661 seconds (80000128 bytes allocated)
奇数,C,是due to it operating in the global scope,其中类型推断不起作用,并且生成较慢的代码。
A和B之间的相对时间由于在第一次使用时编译的功能而受到一些变化的影响。如果我们再次运行它,我们得到
A2: elapsed time: 0.038542212 seconds (80 bytes allocated)
B2: elapsed time: 0.063630172 seconds (80000128 bytes allocated)
这是有意义的,因为A2没有分配内存(80个字节用于函数的返回值),B2创建一个新的向量。另请注意,B2会分配与D相同的内存量 - 第一次是为编译分配的内存。
最后,devectorized vs vectorized是一个个案的基础。例如,如果您使用for循环实现矩阵乘法,并且没有缓存感知,则可能比使用使用BLAS的矢量化A*b
慢得多。
答案 1 :(得分:2)