ArrayAllocators.jl is a Julia language package that provides various methods to allocate memory for arrays. It also implements various ways of calculating the total number of bytes in order to detect integer overflow conditions when multiplying the dimensions of an array and the size of the array elements.
For example, calloc
is a standard C function that allocates memory while initializing the bytes in the memory to 0
, which may be done lazily by some operating sytems as needed. Contrast this with Julia's Base.zeros
which eagerly fills sets all the bytes in memory to 0
. This often means that allocating memory via calloc
may be initially faster than using Base.zeros
.
The Python package NumPy for example, implements numpy.zeros
with calloc
.
At times, numpy.zeros
and Python code using this method may seem to outperform Julia code using Base.zeros
. See the Discourse link under
the discussion below for further details.
Other examples of specialized array allocation techniques include aligned memory on POSIX systems or virtual allocations on Windows systems.
Multiple processor socket systems may also implement Non-Uniform Memory Access (NUMA) memory architecture. To optimally use the NUMA architecture, memory must be explicitly allocated on a specific NUMA node. The subpackage NumaAllocators.jl implements this functionality for Windows and Linux operating systems.
AbstractArrayAllocator
can be provided as first argument when constructing any subtype of AbstractArray
where undef
is usually provided.
Any C function that returns a pointer can be wrapped by the AbstractArrayAllocator
interface by implementing the allocate
method and overriding
Base.unsafe_wrap
.
using Pkg
Pkg.add("ArrayAllocators")
julia> using ArrayAllocators
julia> @time zeros(UInt8, 2048, 2048);
0.000514 seconds (2 allocations: 4.000 MiB)
julia> @time Array{UInt8}(undef, 2048, 2048);
0.000017 seconds (2 allocations: 4.000 MiB)
julia> @time Array{UInt8}(calloc, 2048, 2048); # Allocates zeros, but is much faster than `Base.zeros`
0.000015 seconds (2 allocations: 4.000 MiB)
julia> @time Array{UInt8}(calloc, 20480000, typemax(Int64));
ERROR: OverflowError: 20480000 * 9223372036854775807 overflowed for type Int64
...
julia> using NumaAllocators
julia> @time Array{UInt8}(NumaAllocator(0), 2048, 2048);
0.000010 seconds (2 allocations: 80 bytes)
- NumaAllocators.jl: Allocate memory on Non-Uniform Memory Access (NUMA) nodes
- SafeByteCalculators.jl: Implement byte calculations using SaferIntegers.jl to detect integer overflow. Note that a form of integer overflow detection is implemented in ArrayAllocators.jl itself. This package just provides an alternative implementation.
See https://discourse.julialang.org/t/faster-zeros-with-calloc/69860 for discussion about this approach.
Per LICENSE, ArrayAllocators.jl is licensed under the MIT License.