[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Avoiding LuaJIT FFI allocations (Was: LuaJIT - Is ffi.alloca possible?)
- From: Wolfgang Pupp <wolfgang.pupp@...>
- Date: Sun, 5 Feb 2012 13:19:24 +0100
2012/2/4 Adam Strzelecki <ono@java.pl>:
> I did try already to override __gc for my matrix MT and keep released structures in some kind of cache, unfortunately in tight loops dealllocs are called after to whole loop is finished, so the sequence for 'i = 1, 1000000 do res = mat1 * mat2 end' looks more like 1000000 allocs and then 1000000 deallocs, rather than 1000000 interleaved alloc+dealloc. So caching does not really work there.
Calling collectgarbage periodically from your matrix constructor might
help, if that isn't a big no-no for you...
I experimented around with this code a bit, and the concept seems to work:
local ffi = require( "ffi" )
local M = {_NAME = 'Vector3d', _VERSION = '0.0', _DESCRIPTION =
"Module for 3d-math."}
local ctype
local pool = {}
local gCInterval = 2
local noGcCnt = 0
local function addToPool(v)
pool[#pool+1] = v
end
function M.new(x, y, z)
if noGcCnt >= gCInterval then
collectgarbage 'collect'
noGcCnt = 1
else
noGcCnt = noGcCnt + 1
end
local v
if #pool > 0 then
v = pool[#pool]
pool[#pool] = nil
v.x, v.y, v.z = x, y, z
else
v = ffi.new(ctype, {x=x, y=y, z=z})
end
ffi.gc(v, addToPool)
return v
end
function M.add(a, b)
return M.new(a.x + b.x, a.y + b.y, a.z + b.z)
end
ctype = ffi.metatype('struct {double x, y, z;}', {
__add = M.add,
__tostring = function(v)
return ("Vector3d (%s): {%g, %g,
%g}"):format(tostring(ffi.cast('void *', v)), v.x, v.y, v.z)
end,
})
setmetatable(M, {
__call = function(_, x, y, z) return M.new(x, y, z) end,
})