Strange memory allocation pattern for arrays of different types

Here is en example where I create a few arrays:

module Test2

const N = 10^6

r1 = zeros(UInt8, N)
d1 = ones(Float32, N)
r2 = zeros(UInt8, N)
d2 = ones(Float32, N)
r3 = zeros(UInt8, N)
d3 = ones(Float32, N)

println(pointer(r1), " ", pointer(d1))
println(pointer(r2), " ", pointer(d2))
println(pointer(r3), " ", pointer(d3))

end

and they are allocated consecutively in vastly different areas of memory depending on their element type:

Ptr{UInt8} @0x00000000014f1980 Ptr{Float32} @0x00007f74871dc040
Ptr{UInt8} @0x00000000015e5c40 Ptr{Float32} @0x00007f7486e0b040
Ptr{UInt8} @0x00000000016d9f00 Ptr{Float32} @0x00007f7486a3a040

Why is that?

Could not reproduce:

julia> include("Test2.jl")
Ptr{UInt8} @0x0000000037872040 Ptr{Float32} @0x000000003c623080
Ptr{UInt8} @0x0000000037976300 Ptr{Float32} @0x000000004e018080
Ptr{UInt8} @0x000000004e3f00c0 Ptr{Float32} @0x000000004f3c2080
Main.Test2

julia> versioninfo()
Julia Version 1.5.0
Commit 96786e22cc (2020-08-01 23:44 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: AMD Ryzen 5 3600 6-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, znver1)

That’s certainly the memory management of the operating system. I don’t think Julia is in charge of controlling that, but I am not sure since there are so many hacks you can do on the lower level :wink:

In VSCode with Julia, I’m getting the artifact I reported:

Ptr{UInt8} @0x00000000055b9680 - Ptr{Float32} @0x00007f986fc2c040
Ptr{UInt8} @0x00000000056ad940 - Ptr{Float32} @0x00007f986f85b040
Ptr{UInt8} @0x00000000057a1c40 - Ptr{Float32} @0x00007f986f48a040
Main.Test2

julia> versioninfo()
Julia Version 1.5.0
Commit 96786e22cc (2020-08-01 23:44 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)

but when I run it in terminal, artifact disappears and allocations are in the same memory area:

Ptr{UInt8} @0x00007fadd4ad4040 - Ptr{Float32} @0x00007fadd4703040
Ptr{UInt8} @0x00007fadd460e040 - Ptr{Float32} @0x00007fadd423d040
Ptr{UInt8} @0x00007fadd4148040 - Ptr{Float32} @0x00007fadd3d77040
Main.Test2

julia> versioninfo()
Julia Version 1.5.0
Commit 96786e22cc (2020-08-01 23:44 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)

I’m bringing this issue up because during my work on wrapping a C library, I was fighting unexpected memory addressing issues and behavior differences between building with VSCode and plain command line.

Doing the same in VSCode REPL it’s the same:

julia> cd("c:\\Temp")

julia> include("Test2.jl")
Ptr{UInt8} @0x00000000368700c0 Ptr{Float32} @0x0000000041206080
Ptr{UInt8} @0x0000000038194a40 Ptr{Float32} @0x00000000415eb080
Ptr{UInt8} @0x0000000038068f40 Ptr{Float32} @0x00000000419cd080
Main.Test2

How do you call your module Test2?

I tried both Julia: Execute File and

julia> include("test-2.jl")

with the same result, i.e. artifact is still there.

EDIT

I just rebooted the system and it behaves the same.

I did the same and still not reproducing:

Ptr{UInt8} @0x0000000036c69000 Ptr{Float32} @0x00000000411ca080
Ptr{UInt8} @0x000000003833bfc0 Ptr{Float32} @0x00000000415a8080
Ptr{UInt8} @0x000000003815ff00 Ptr{Float32} @0x0000000041984080
Main.Test2

julia>

I second above statement about operating system.

It seems to depend on requested memory size. When I change the test to:

module Test2

const N = 10^6
const M = 10^5

r1 = zeros(UInt8, N)
d1 = ones(Float32, M)
r2 = zeros(UInt8, N)
d2 = ones(Float32, M)
r3 = zeros(UInt8, N)
d3 = ones(Float32, N)

println(pointer(r1), " - ", pointer(d1))
println(pointer(r2), " - ", pointer(d2))
println(pointer(r3), " - ", pointer(d3))

end

the artifact is present for large (4MB) allocation:

Ptr{UInt8} @0x0000000001c9e3c0 - Ptr{Float32} @0x0000000001d92680
Ptr{UInt8} @0x0000000001df4140 - Ptr{Float32} @0x0000000001ee8400
Ptr{UInt8} @0x0000000001f49ec0 - Ptr{Float32} @0x00007f85c5567040

My second Ubuntu 18.04 system behaves the same way.