Julia代码优化,结构和原始类型之间的区别? (内存分配)

时间:2018-05-31 16:20:33

标签: optimization julia

我有一些代码可以针对某些关键部分进行优化,我不希望gc触发内存分配。

更确切地说,我有一个实数类型

struct AFloat{T<:AbstractFloat} <: Real
    value::T
    j::Int 
end

我必须跟踪以执行自动区分。因此,对于任何算术运算,我必须在磁带中进行一些注册。性能在这里非常重要(如果你对每个算术运算有一个更多的分配,它会产生真正的不同!)。我可以选择AFloat{T}或简单地使用基本类型来跟踪索引j:

primitive type AFloat64 <: Real sizeof(Int) end

但是,我对这些结果感到困惑:

第一部分:好的

using BenchmarkTools

struct A n::Int64 end

vA=A[A(1)];
@time push!(vA,A(2))

v=Int64[1];
@time push!(v,2)

返回

0.000011 seconds (6 allocations: 224 bytes)
0.000006 seconds (5 allocations: 208 bytes)

与以下内容相符:

@btime push!(vA,A(2))
@btime push!(v,2)

返回

  46.410 ns (1 allocation: 16 bytes)
  37.890 ns (0 allocations: 0 bytes)

- &GT;我会得出结论,与 struct 相比,推动原语类型避免一个内存分配(是不是?)

第二部分:......有问题......?

我感到困惑,我无法解释这些结果:

foo_A() = A(1);             
foo_F64() = Float64(1.);                
foo_I64() = Int64(1);             

@time foo_A()
@time foo_F64()
@time foo_I64()

返回

  0.000004 seconds (5 allocations: 176 bytes)
  0.000005 seconds (5 allocations: 176 bytes)
  0.000005 seconds (4 allocations: 160 bytes)

Q1如何解释差异foo_F64()与foo_I64()(5分配vs 4分配)?

此外,结果似乎与@btime输出不一致:

@btime foo_A()
  3.179 ns (0 allocations: 0 bytes)

@btime foo_F64()
  3.801 ns (0 allocations: 0 bytes)

@btime foo_I64()
  3.180 ns (0 allocations: 0 bytes)

Q2:@time或@btime的答案是什么?为什么?

合成,在Julia中, foo_A foo_Primitive 之间的性能和内存分配存在差异,其中:< / p>

struct A n::Int64 end

foo_A() = A(1)
foo_Primitive() = Int64(1)

我知道使用@time或@btime时,使用如此小的表达式会产生副作用的风险。理想情况下,最好有一些朱莉娅的内部知识来回答。但我不

julia> versioninfo()
Julia Version 0.6.2
Commit d386e40c17 (2017-12-13 18:08 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU E5-2603 v3 @ 1.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)

1 个答案:

答案 0 :(得分:1)

您所看到的分配只是来自REPL afaict的时间副作用 如果你把它们放在一个函数中,那么你使用结构或基本类型的分配是相同的:

julia> function f()
           vA=[A(1)]
           @time push!(vA,A(2))

           v=[1]
           @time push!(v,2)
       end
f (generic function with 1 method)

julia> f();
  0.000000 seconds (1 allocation: 32 bytes)
  0.000000 seconds (1 allocation: 32 bytes)