Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 这一基准结果的原因是什么?_Loops_Benchmarking_Vectorization_Julia - Fatal编程技术网

Loops 这一基准结果的原因是什么?

Loops 这一基准结果的原因是什么?,loops,benchmarking,vectorization,julia,Loops,Benchmarking,Vectorization,Julia,将rgb图像转换为灰度图像的两个函数: function rgb2gray_loop{T<:FloatingPoint}(A::Array{T,3}) r,c = size(A) gray = similar(A,r,c) for i = 1:r for j = 1:c @inbounds gray[i,j] = 0.299*A[i,j,1] + 0.587*A[i,j,2] + 0.114 *A[i,j,3] end end return

将rgb图像转换为灰度图像的两个函数:

function rgb2gray_loop{T<:FloatingPoint}(A::Array{T,3})
  r,c = size(A)
  gray = similar(A,r,c)
  for i = 1:r
    for j = 1:c
      @inbounds gray[i,j] = 0.299*A[i,j,1] + 0.587*A[i,j,2] + 0.114 *A[i,j,3]
    end
  end
  return gray
end
A=rand(500500,3)

A=兰特(50005000,3)

我期望一个函数比另一个函数快(可能是f1,因为inbounds宏)

但我无法解释,为什么矢量化版本对于更大的图像速度更快。
这是为什么?

只是猜测,因为我不认识朱莉娅·朗:


我认为向量化形式中的语句
gray=…
创建了一个新数组,其中存储了所有计算值,而旧数组被废弃。在
f1
中,值被就地覆盖,因此不需要新的内存分配。内存分配非常昂贵,因此对于低数字,具有就地覆盖的循环版本速度更快


但内存分配通常是一种静态开销(分配两倍并不需要两倍的时间),矢量化版本的计算速度更快(可能是并行的?),因此,如果数字足够大,则更快的计算会比内存分配产生更大的差异。

我无法重现您的结果

请参阅此IJulia笔记本:

我得到的数字是:

In [5]:

@time rgb2gray_loop(rand(50,50,3));
@time rgb2gray_vec(rand(50,50,3));

elapsed time: 7.591e-5 seconds (80344 bytes allocated)
elapsed time: 0.000108785 seconds (241192 bytes allocated)

In [6]:

@time rgb2gray_loop(rand(500,500,3));
@time rgb2gray_vec(rand(500,500,3));

elapsed time: 0.021647914 seconds (8000344 bytes allocated)
elapsed time: 0.012364489 seconds (24001192 bytes allocated)

In [7]:

@time rgb2gray_loop(rand(5000,5000,3));
@time rgb2gray_vec(rand(5000,5000,3));

elapsed time: 0.902367223 seconds (800000440 bytes allocated)
elapsed time: 1.237281103 seconds (2400001592 bytes allocated, 7.61% gc time)
正如预期的那样,对于大输入,循环版本更快。还要注意矢量化版本如何分配三倍的内存

我还想指出,语句
gray=similor(A,size(A)[1:2]…)
是多余的,可以省略。 如果没有这种不必要的分配,最大问题的结果是:

@time rgb2gray_loop(rand(5000,5000,3));
@time rgb2gray_vec(rand(5000,5000,3));

elapsed time: 0.953746863 seconds (800000488 bytes allocated, 3.06% gc time)
elapsed time: 1.203013639 seconds (2200001200 bytes allocated, 7.28% gc time)

因此,内存使用率下降了,但速度没有明显提高。

结果的答案是Julia中的多维数组是按列主顺序存储的。看

固定循环版本,关于列主顺序(内部和外部循环变量交换):

对于较小的阵列,结果如下:

A=rand(500500,3)

A=rand(50,50,3)


我认为向量化版本中的语句
gray=similor(A,size(A)[1:2]…)
是不必要的,该语言将直接从第二个语句创建适当的数组大小。这并不能解释为什么矢量化的版本变得更快,虽然是.Off-topic,但是如果你使用图像,你可以说
convert(Array{Gray{Float64}},A)
。在Julia中,矢量化的操作通常比元素化的慢,因为后者产生的时间更少。这里的矢量化版本将创建三个临时数组,然后将它们相加,而elementwise版本不需要任何额外的临时数组,只使用一个循环。@cfh这就是我所想的-对于矢量化,内存影响更大。但另一方面,矢量化版本可以在4个核上并行计算。而且可能存在一个收支平衡点,4倍CPU带来的好处比内存分配成本更大。你测试过四核吗?我不认为这些计算会自动分布在Julia的核上。我可以用@time重现我的结果。我猜Falco是对的,结果与我机器上的某种并行化有关……@reschu:听起来不对。首先,Julia不会自动并行化。还请注意,循环版本的给定时间随问题的大小而线性增长:从第二个问题到第三个问题,速度慢了200倍,尽管问题的大小只大了100倍。那里一定发生了什么奇怪的事。是的,你是对的。我发现了这是什么。我第一次读到的东西是从Julia开始的:Column major order。在嵌套循环中交换行和列会得到预期的结果。@reschu:这很有趣!你能补充一个答案来描述你做了什么吗?我也可能不得不收回我的声明,Julia不会自动并行化——它使用OpenBLAS,在某些情况下可以利用多核。所以这可能是这两个因素的结合。很好。您还可以在循环中尝试
@simd
宏,看看它是否能进一步加快速度?
| Row | Function | Average    | Relative | Replications |
|-----|----------|------------|----------|--------------|
| 1   | "f1"     | 0.00783007 | 1.0      | 100          |
| 2   | "f2"     | 0.0153099  | 1.95527  | 100          |
| Row | Function | Average  | Relative | Replications |
|-----|----------|----------|----------|--------------|
| 1   | "f1"     | 1.60534  | 2.56553  | 10           |
| 2   | "f2"     | 0.625734 | 1.0      | 10           |
In [5]:

@time rgb2gray_loop(rand(50,50,3));
@time rgb2gray_vec(rand(50,50,3));

elapsed time: 7.591e-5 seconds (80344 bytes allocated)
elapsed time: 0.000108785 seconds (241192 bytes allocated)

In [6]:

@time rgb2gray_loop(rand(500,500,3));
@time rgb2gray_vec(rand(500,500,3));

elapsed time: 0.021647914 seconds (8000344 bytes allocated)
elapsed time: 0.012364489 seconds (24001192 bytes allocated)

In [7]:

@time rgb2gray_loop(rand(5000,5000,3));
@time rgb2gray_vec(rand(5000,5000,3));

elapsed time: 0.902367223 seconds (800000440 bytes allocated)
elapsed time: 1.237281103 seconds (2400001592 bytes allocated, 7.61% gc time)
@time rgb2gray_loop(rand(5000,5000,3));
@time rgb2gray_vec(rand(5000,5000,3));

elapsed time: 0.953746863 seconds (800000488 bytes allocated, 3.06% gc time)
elapsed time: 1.203013639 seconds (2200001200 bytes allocated, 7.28% gc time)
function rgb2gray_loop{T<:FloatingPoint}(A::Array{T,3})
  r,c = size(A)
  gray = similar(A,r,c)
  for j = 1:c
    for i = 1:r
      @inbounds gray[i,j] = 0.299*A[i,j,1] + 0.587*A[i,j,2] + 0.114 *A[i,j,3]
    end
  end
  return gray
end
| Row | Function | Average  | Relative | Replications |
|-----|----------|----------|----------|--------------|
| 1   | "f1"     | 0.107275 | 1.0      | 10           |
| 2   | "f2"     | 0.646872 | 6.03004  | 10           |
| Row | Function | Average    | Relative | Replications |
|-----|----------|------------|----------|--------------|
| 1   | "f1"     | 0.00236405 | 1.0      | 100          |
| 2   | "f2"     | 0.0207249  | 8.76671  | 100          |
| Row | Function | Average     | Relative | Replications |
|-----|----------|-------------|----------|--------------|
| 1   | "f1"     | 4.29321e-5  | 1.0      | 1000         |
| 2   | "f2"     | 0.000224518 | 5.22961  | 1000         |