-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Brl.Map] Map or GC: using "C-Maps" leads to stutter #258
Comments
I replaced void bmx_map_intmap_insert( int key, BBObject *value, struct avl_root ** root ) {
struct intmap_node * node = (struct intmap_node *)GC_malloc_uncollectable(sizeof(struct intmap_node));
node->key = key;
node->value = value;
struct intmap_node * old_node = (struct intmap_node *)avl_map(&node->link, compare_intmap_nodes, root);
if (&node->link != &old_node->link) {
// key already exists. Store the value in this node.
old_node->value = value;
// delete the new node, since we don't need it
GC_FREE(node);
}
} with void bmx_map_intmap_insert( int key, BBObject *value, struct avl_root ** root ) {
struct intmap_node node;
node.key = key;
struct intmap_node * found = (struct intmap_node *)TREE_SEARCH(&node, compare_intmap_nodes, root);
if (found) {
//nothing to do
}else{
//insert new
struct intmap_node * node = (struct intmap_node *)GC_malloc_uncollectable(sizeof(struct intmap_node));
node->key = key;
node->value = value;
avl_add(&node->link, compare_intmap_nodes, root);
}
} (maybe one could still use "avl_map" and then replace the pointer with a gc_malloc_... marked one) A simple benchmark:
resulted in 260ms for "new" (lookup + add), and 195ms for "old" (avl_map). |
Interesting bit: my "new code" segfaults if I have a loop of 10.000.000 instead of 1.000.000:
|
I replaced my code with this: void bmx_map_intmap_insert( int key, BBObject *value, struct avl_root ** root ) {
struct avl_root link;
struct intmap_node * old_node = (struct intmap_node *)avl_map(&link, compare_intmap_nodes, root);
// key already exists. Store the value in this node.
if (&link != &old_node->link) {
old_node->value = value;
// key did not exist. replace node with a managed one
}else{
//struct intmap_node * gcmanaged_node = (struct intmap_node *)GC_malloc_explicitly_typed(sizeof(struct intmap_node), maxIntMapDescr);
struct intmap_node * gcmanaged_node = (struct intmap_node *)GC_malloc_uncollectable(sizeof(struct intmap_node));
gcmanaged_node->key = key;
gcmanaged_node->value = value;
gcmanaged_node->link = link;
}
} which reduced the benchmark time to 186ms here. Yet this does not detect "already existing" (how should it - with a "new" Link while the original code just pointed to the first element in the node-struct.) So I am looking for a way to override a "previously non gc-managed" node with a "now gc managed" one. This would allow to get rid of the unneeded gc-allocs. PS: I understand that a Map is not intended to be "overwritten" whole the time but as it is not forbidden ... it might be good to increase performance for the "overwriting part" (avoiding nonneeded stuff) Edit: seems it is not that easy to replace a "stack" allocated node with a "heap" allocated one. My code is not overwriting many map entries (reusing "same key") that often - not often enough to make a difference regarding stuttering. So it most probably is something else (very hard to find out if I cannot replicate it locally) |
Got a handful more reports about that stuttering. So it is less rare than first assumed (especially if you consider how likely you get feedback from users). @woollybah Were you somehow able to replicate such an issue or should I try to create a complete "sample app" ? I assume it only stutters if you create a lot of objects for the c-maps, then delete it AND then are "normally" using the GC (so doing your normal app logic stuff). |
using this a multiple times made my game stutter on that users computer from then on. It never "calmed down" .
replacing "TIntMap" with "TMap" and using
string(pointCount)
as key - and no stutter happens.TIntMap and the likes (The ones written with C-Code) use:
GC_malloc_uncollectable defined in blitz.mod/bdwgc/include/gc/gc.h:
Dunno if the GC is bugged there ... and does not get rid of "what to scan" or if the TIntMap (and consortes) implementation does not "free" correctly?
The text was updated successfully, but these errors were encountered: