Untimely garbage collection
Scott Lystig Fritchie
fritchie@REDACTED
Sat Jul 13 21:54:20 CEST 2002
In preparing for the upcoming ACM PLI Erlang workshop, I'm suddenly
*very* interested in the issues Shawn raises. I'll split my comments
& questions into two messages ... two short messages are harder to
ignore (intentionally or accidentally) than a single long message.
:-)
>>>>> "sp" == Shawn Pearce <spearce@REDACTED> writes:
sp> When the second gen_server gets the binaries, it sends them to the
sp> port using Port ! {self(), {command, List}}, where List is the
sp> List of ErlDrvBinary objects given to Erts by the bt848 driver.
The docs & erts code seem to imply that erlang:port_command/2 is the
preferred way of doing that. {shrug}
Would I be correct to guess that your XVideo driver defines the
'outputv' method and that its 'outputv' handler accesses the pointers
inside of the ErlIOVec directly (to avoid unnecessary data copies)?
sp> Initial testing showed that allocating ErlDrvBinary objects for
sp> each video frame was far too costly in CPU time. The allocator is
sp> just too slow.
Really? You really be moving a *lot* of data through those drivers.
Or, if after allocating a ErlDrvBinary, you don't have enough time to
copy the frame into the new ErlDrvBinary without dropping some data?
Perhaps this strategy would be useful? Have the bt848 driver allocate
a single (or a small number of) ErlDrvBinary large enough to hold
several frames worth of data. The driver can choose the offset in a
ErlDrvBinary to deposit the next frame's data. Hrm ... it isn't
obvious if this would lower your overhead or not.
sp> From the perspective of my application, it would be ok
sp> for my Erlang servers to notify the C drivers when they are done
sp> with the binary so it can rewrite it, regardless of the refc.
I had a brainstorm I had yesterday on this topic. Consider this
example from the SWIG (http://www.swig.org/) documentation:
# Copy a file
def filecopy(source,target):
f1 = fopen(source, "r")
f2 = fopen(target, "w")
buffer = malloc(8192)
nbytes = fread(buffer,8192,1,f1)
while (nbytes > 0):
fwrite(buffer,8192,1,f2)
nbytes = fread(buffer,8192,1,f1)
free(buffer)
An Erlang driver cannot implement malloc and fread in this manner
because of its assumption of multiple assignment.
But, what if the local Erlang process knew that certain binaries were
multiple-assignment-capable? Then it could safely work like filecopy
above *if* it were written carefully. This might be viable if two
things were added:
1. If the owner process of such a binary were to send it
to another process, the ErlDrvBinary data would be _copied_ so
that the multiple-assignment-ignorant receiver could
blissfully assume single-assignment semantics?
2. The driver implemented a copy method so that the owner
process could make a single-assignment "snapshot" of the
multiple-assignment binary for long-term keeping.
Is this a good idea? {shrug}
-Scott
More information about the erlang-questions
mailing list