Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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
Arrays 使用数组视图时出现意外内存分配(julia)_Arrays_Performance_Julia_Allocation - Fatal编程技术网

Arrays 使用数组视图时出现意外内存分配(julia)

Arrays 使用数组视图时出现意外内存分配(julia),arrays,performance,julia,allocation,Arrays,Performance,Julia,Allocation,我试图在数组X中搜索所需的模式(变量模板)。模板的长度为9 我在做一些事情,比如: function check_alloc{T <: ZeroOne}(x :: AbstractArray{T}, temp :: AbstractArray{T}) s = 0 for i in 1 : 1000 myView = view(x, i : i + 9) if myView == temp s += 1

我试图在数组X中搜索所需的模式(变量模板)。模板的长度为9

我在做一些事情,比如:

function check_alloc{T <: ZeroOne}(x :: AbstractArray{T}, temp :: AbstractArray{T})
    s = 0
    for i in 1 : 1000
        myView = view(x, i : i + 9)
        if myView == temp
            s += 1
        end
    end
    return s
end

function check\u alloc{T这至少适用于任意大小的
temp
x
但仍有~KB的分配

function check_alloc{T}(x :: AbstractArray{T}, temp :: AbstractArray{T})
    s = 0
    pl = length(temp)
    for i in 1:length(x)-pl+1
        @views if x[i:i+pl-1] == temp
            s += 1
        end
    end
    return s
end
编辑:正如@Sairus在评论中所建议的,我们可以本着以下精神做一些事情:

function check_alloc2{T}(x :: AbstractArray{T}, temp :: AbstractArray{T})
    s = 0
    pl = length(temp)
    plr = 1:pl
    for i in 1:length(x)-pl+1
        same = true
        for k in plr
            @inbounds if x[i+k-1] != temp[k]
                same = false
                break
            end
        end
        if same
            s+=1
        end
    end
    return s
end
这没有分配:

julia> using BenchmarkTools

julia> a = collect(1:1000);

julia> b = collect(5:12);

julia> @btime check_alloc2($a,$b);
  1.195 μs (0 allocations: 0 bytes)

您获得分配的原因是
view(A,i:i+9)
创建了一个称为
子数组的小对象。这只是一个“包装器”,基本上存储了对
A
的引用和您传入的索引(
i:i+9
)。因为包装器很小(对于一维对象约40字节),有两种合理的存储方法:““分配”仅指堆内存,因此如果Julia可以将包装器存储在堆栈上,它将报告没有分配(而且速度更快)

不幸的是,目前一些
子阵列
对象(截至2017年底)必须存储在堆上。原因是Julia是一种语言,这意味着如果
a
是一个不再使用的堆分配对象,那么
a
可能会从内存中释放。关键点是:当前,只有当这些变量存储在因此,如果所有
子数组
都存储在堆栈上,那么您将遇到如下代码问题:

function create()
    A = rand(1000)
    getfirst(view(A, 1:10))
end

function getfirst(v)
    gc()   # this triggers garbage collection
    first(v)
end
由于
create
在调用
getfirst
后不会再次使用
A
,因此它不会“保护”
A
。风险在于
gc
调用可能会释放与
A
相关的内存(从而中断
v
本身中条目的任何使用,因为
v
依赖于
A
),除非使用
v
可以防止
A
被垃圾收集。但目前,堆栈分配的变量无法保护堆分配的内存:垃圾收集器只扫描堆上的变量


您可以使用您的原始函数来观察这一点,通过去掉(不相关,出于这些目的)将其修改为限制性稍小一些
t什么是
ZeroOne
?另外,您说您正在搜索的模式长度为9,但您正在创建一个长度为10的视图
i:i+9
。这不是关于
视图
,而是
=
操作(您可以注释掉它并查看
@time
)。您可以手动重写此比较或查看
@edit>(==)(AbstractArray[],AbstractArray[])
也许还可以看看ZeroOne是联合体{Bool,Int8,UInt8}。视图的确不需要内存来创建,但为什么(==)操作这么慢?为什么需要这么多内存?
==
没有创建临时数组,但是
==
创建了。非常感谢!我对这种情况完全感到困惑。(==)真的需要它吗分配这么多内存的操作?感谢您分享关于幕后发生的事情的深入知识。从-。
function check_alloc(x::AbstractArray{T}, temp::AbstractArray{T}) where T
    s = 0
    for i in 1 : 1000
        myView = view(x, i : i + 9)
        if myView == temp
            s += 1
        end
    end
    return s
end

a = collect(1:1010);      # this uses heap-allocated memory
b = collect(1:10);

@time check_alloc(a, b);  # ignore the first due to JIT-compilation
@time check_alloc(a, b)

a = 1:1010                # this doesn't require heap-allocated memory
@time check_alloc(a, b);  # ignore due to JIT-compilation
@time check_alloc(a, b)
julia> @time check_alloc(a, b)
  0.000022 seconds (1.00 k allocations: 47.031 KiB)
julia> @time check_alloc(a, b)
  0.000020 seconds (4 allocations: 160 bytes)