From 8c9a5d2d25e06c5775840a1c0eeef53901b0d014 Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Thu, 1 Aug 2024 16:04:42 -0500 Subject: [PATCH 1/4] free_memory: Optimize reading meminfo --- src/storage.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/storage.jl b/src/storage.jl index 007be09..18d3741 100644 --- a/src/storage.jl +++ b/src/storage.jl @@ -163,12 +163,11 @@ struct CPURAMResource <: StorageResource end if Sys.islinux() function free_memory() open("/proc/meminfo", "r") do io - # skip first 2 lines - readline(io) - readline(io) - line = readline(io) - free = match(r"MemAvailable:\s*([0-9]*)\s.*", line).captures[1] - parse(UInt64, free) * 1024 + # TODO: Cache in TLS + buf = zeros(UInt8, 128) + readbytes!(io, buf) + free = match(r"MemAvailable:\s*([0-9]*)\s.*", String(buf)).captures[1] + return parse(UInt64, free) * 1024 end end else From f3cff0551a33ef1df1f051d9222f462c2c8c10de Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Thu, 1 Aug 2024 16:05:50 -0500 Subject: [PATCH 2/4] approx_size: Specialize on object type, use sizeof --- src/MemPool.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/MemPool.jl b/src/MemPool.jl index bd0af68..6f800ed 100644 --- a/src/MemPool.jl +++ b/src/MemPool.jl @@ -63,8 +63,12 @@ include("datastore.jl") Returns the size of `d` in bytes used for accounting in MemPool datastore. """ -function approx_size(@nospecialize(d)) - Base.summarysize(d) # note: this is accurate but expensive +function approx_size(d::T) where T + if Base.datatype_pointerfree(T) + return sizeof(d) + else + Base.summarysize(d) # note: this is accurate but expensive + end end function approx_size(d::Union{Base.BitInteger, Float16, Float32, Float64}) From 4fb66fce8f00085e65ad6cfcb1757b7db4c9afc6 Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Thu, 1 Aug 2024 16:06:36 -0500 Subject: [PATCH 3/4] ensure_mem: Object was already allocated --- src/datastore.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/datastore.jl b/src/datastore.jl index 4b1a7bf..e6a9fd7 100644 --- a/src/datastore.jl +++ b/src/datastore.jl @@ -385,7 +385,7 @@ const MEM_RESERVE_LOCK = Threads.ReentrantLock() const MEM_RESERVE_SWEEPS = Ref{Int}(3) """ -When called, ensures that at least `MEM_RESERVED[] + size` bytes are available +When called, ensures that at least `MEM_RESERVED[]` bytes are available to the OS. If there is not enough memory available, then a variety of calls to the GC are performed to free up memory until either the reservation limit is satisfied, or `max_sweeps` number of cycles have elapsed. @@ -396,7 +396,7 @@ function ensure_memory_reserved(size::Integer=0; max_sweeps::Integer=MEM_RESERVE max_sweeps == 0 && return # Do a quick (cached) check, to optimize for many calls to this function when memory isn't tight - if Int(storage_available(CPURAMResource())) - size >= MEM_RESERVED[] + if Int(storage_available(CPURAMResource())) >= MEM_RESERVED[] return end @@ -404,7 +404,7 @@ function ensure_memory_reserved(size::Integer=0; max_sweeps::Integer=MEM_RESERVE sweep_ctr = 0 while true with(QUERY_MEM_OVERRIDE => true) do - Int(storage_available(CPURAMResource())) - size < MEM_RESERVED[] + Int(storage_available(CPURAMResource())) < MEM_RESERVED[] end || break # We need more memory! Let's encourage the GC to clear some memory... From 8107627c71e868c15edef0c48897b181b7503d0c Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Thu, 1 Aug 2024 16:06:57 -0500 Subject: [PATCH 4/4] ensure_mem: Wait for empty SEND_QUEUE --- src/datastore.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datastore.jl b/src/datastore.jl index e6a9fd7..5d4e9fa 100644 --- a/src/datastore.jl +++ b/src/datastore.jl @@ -425,7 +425,7 @@ function ensure_memory_reserved(size::Integer=0; max_sweeps::Integer=MEM_RESERVE yield() # Wait for send queue to clear - while SEND_QUEUE.processing + while SEND_QUEUE.processing || !isempty(SEND_QUEUE.queue) yield() end