mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2026-09-18 09:34:36 +07:00
fix batch optimizations with reallocs
This commit is contained in:
@@ -19,10 +19,18 @@ local DOUBLE_TYPEOF = ffi.typeof('double')
|
||||
local DOUBLE_SIZEOF = ffi.sizeof(DOUBLE_TYPEOF)
|
||||
local DOUBLE_STORAGE_TYPEOF = ffi.typeof('$[?]', DOUBLE_TYPEOF)
|
||||
|
||||
local STORAGE_SIZES = {}
|
||||
|
||||
---@type evolved.realloc
|
||||
local function float_realloc(old_storage, old_size, new_size)
|
||||
if old_storage then
|
||||
assert(STORAGE_SIZES[old_storage] == old_size)
|
||||
end
|
||||
|
||||
local new_storage = ffi.new(FLOAT_STORAGE_TYPEOF, new_size + 1)
|
||||
|
||||
STORAGE_SIZES[new_storage] = new_size
|
||||
|
||||
if old_storage then
|
||||
ffi.copy(new_storage + 1, old_storage + 1, math.min(old_size, new_size) * FLOAT_SIZEOF)
|
||||
end
|
||||
@@ -32,8 +40,14 @@ end
|
||||
|
||||
---@type evolved.realloc
|
||||
local function double_realloc(old_storage, old_size, new_size)
|
||||
if old_storage then
|
||||
assert(STORAGE_SIZES[old_storage] == old_size)
|
||||
end
|
||||
|
||||
local new_storage = ffi.new(DOUBLE_STORAGE_TYPEOF, new_size + 1)
|
||||
|
||||
STORAGE_SIZES[new_storage] = new_size
|
||||
|
||||
if old_storage then
|
||||
ffi.copy(new_storage + 1, old_storage + 1, math.min(old_size, new_size) * DOUBLE_SIZEOF)
|
||||
end
|
||||
@@ -299,3 +313,89 @@ do
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
evo.collect_garbage()
|
||||
|
||||
local f1 = evo.builder():name('f1'):realloc(double_realloc):compmove(double_compmove):build()
|
||||
local f2 = evo.builder():name('f2'):realloc(double_realloc):compmove(double_compmove):build()
|
||||
|
||||
local q1 = evo.builder():include(f1):build()
|
||||
local q2 = evo.builder():include(f2):build()
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(40, { [f2] = 2 })
|
||||
for i = 1, ec do
|
||||
assert(not evo.has(es[i], f1))
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 2)
|
||||
end
|
||||
evo.batch_destroy(q2)
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(50, { [f1] = 1, [f2] = 2 })
|
||||
for i = 1, ec do
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 1)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 2)
|
||||
end
|
||||
|
||||
evo.batch_remove(q1, f1)
|
||||
for i = 1, ec do
|
||||
assert(not evo.has(es[i], f1))
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 2)
|
||||
end
|
||||
|
||||
evo.batch_destroy(q1, q2)
|
||||
end
|
||||
|
||||
do
|
||||
evo.spawn({ [f1] = 1 })
|
||||
evo.spawn({ [f2] = 2 })
|
||||
evo.spawn({ [f1] = 1, [f2] = 2 })
|
||||
end
|
||||
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
do
|
||||
evo.collect_garbage()
|
||||
|
||||
local f1 = evo.builder():name('f1'):realloc(double_realloc):compmove(double_compmove):build()
|
||||
local f2 = evo.builder():name('f2'):realloc(double_realloc):compmove(double_compmove):build()
|
||||
|
||||
local q1 = evo.builder():include(f1):build()
|
||||
local q2 = evo.builder():include(f2):build()
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(40, { [f1] = 1, [f2] = 2 })
|
||||
for i = 1, ec do
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 1)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 2)
|
||||
end
|
||||
evo.batch_destroy(q2)
|
||||
end
|
||||
|
||||
do
|
||||
local es, ec = evo.multi_spawn(50, { [f1] = 1 })
|
||||
for i = 1, ec do
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 1)
|
||||
assert(not evo.has(es[i], f2))
|
||||
end
|
||||
|
||||
evo.batch_set(q1, f2, 2)
|
||||
for i = 1, ec do
|
||||
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 1)
|
||||
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 2)
|
||||
end
|
||||
|
||||
evo.batch_destroy(q1, q2)
|
||||
end
|
||||
|
||||
do
|
||||
evo.spawn({ [f1] = 1 })
|
||||
evo.spawn({ [f2] = 2 })
|
||||
evo.spawn({ [f1] = 1, [f2] = 2 })
|
||||
end
|
||||
|
||||
evo.collect_garbage()
|
||||
end
|
||||
|
||||
+68
-27
@@ -2900,10 +2900,6 @@ function __expand_chunk(chunk, min_capacity)
|
||||
__error_fmt('this operation should be deferred')
|
||||
end
|
||||
|
||||
if min_capacity < 4 then
|
||||
min_capacity = 4
|
||||
end
|
||||
|
||||
local entity_count = chunk.__entity_count
|
||||
|
||||
if min_capacity < entity_count then
|
||||
@@ -2922,6 +2918,10 @@ function __expand_chunk(chunk, min_capacity)
|
||||
new_capacity = min_capacity
|
||||
end
|
||||
|
||||
if new_capacity < 4 then
|
||||
new_capacity = 4
|
||||
end
|
||||
|
||||
if chunk.__has_storage_reallocs then
|
||||
local component_count = chunk.__component_count
|
||||
local component_storages = chunk.__component_storages
|
||||
@@ -2945,13 +2945,12 @@ function __expand_chunk(chunk, min_capacity)
|
||||
end
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
function __shrink_chunk(chunk)
|
||||
---@param min_capacity integer
|
||||
function __shrink_chunk(chunk, min_capacity)
|
||||
if __defer_depth <= 0 then
|
||||
__error_fmt('this operation should be deferred')
|
||||
end
|
||||
|
||||
local min_capacity = 4
|
||||
|
||||
local entity_count = chunk.__entity_count
|
||||
|
||||
if min_capacity < entity_count then
|
||||
@@ -3349,10 +3348,28 @@ function __chunk_set(old_chunk, fragment, component)
|
||||
|
||||
for old_ci = 1, old_component_count do
|
||||
local old_f = old_component_fragments[old_ci]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
|
||||
old_component_storages[old_ci], new_component_storages[new_ci] =
|
||||
new_component_storages[new_ci], old_component_storages[old_ci]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
local new_cr = new_component_reallocs[new_ci]
|
||||
|
||||
if new_cr then
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
else
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
else
|
||||
old_component_storages[old_ci], new_component_storages[new_ci] =
|
||||
new_component_storages[new_ci], old_component_storages[old_ci]
|
||||
end
|
||||
end
|
||||
|
||||
new_chunk.__entity_count = sum_entity_count
|
||||
@@ -3364,14 +3381,17 @@ function __chunk_set(old_chunk, fragment, component)
|
||||
local new_ci = new_component_indices[old_f]
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
local new_cr = new_component_reallocs[new_ci]
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
elseif new_cr then
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
if new_cr then
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
else
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
else
|
||||
__lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
@@ -3677,10 +3697,28 @@ function __chunk_remove(old_chunk, ...)
|
||||
|
||||
for new_ci = 1, new_component_count do
|
||||
local new_f = new_component_fragments[new_ci]
|
||||
local new_cr = new_component_reallocs[new_ci]
|
||||
|
||||
local old_ci = old_component_indices[new_f]
|
||||
|
||||
old_component_storages[old_ci], new_component_storages[new_ci] =
|
||||
new_component_storages[new_ci], old_component_storages[old_ci]
|
||||
if new_cr then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
else
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
else
|
||||
old_component_storages[old_ci], new_component_storages[new_ci] =
|
||||
new_component_storages[new_ci], old_component_storages[old_ci]
|
||||
end
|
||||
end
|
||||
|
||||
new_chunk.__entity_count = sum_entity_count
|
||||
@@ -3689,17 +3727,20 @@ function __chunk_remove(old_chunk, ...)
|
||||
local new_f = new_component_fragments[new_ci]
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
local new_cr = new_component_reallocs[new_ci]
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
local old_ci = old_component_indices[new_f]
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
elseif new_cr then
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
if new_cr then
|
||||
local new_cm = new_component_compmoves[new_ci]
|
||||
|
||||
if new_cm then
|
||||
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
else
|
||||
for old_place = 1, old_entity_count do
|
||||
local new_place = new_entity_count + old_place
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
else
|
||||
__lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
|
||||
@@ -5669,7 +5710,7 @@ function __evolved_collect_garbage()
|
||||
if should_be_purged then
|
||||
__purge_chunk(postorder_chunk)
|
||||
else
|
||||
__shrink_chunk(postorder_chunk)
|
||||
__shrink_chunk(postorder_chunk, 0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user