X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=stat.c;h=b9df032a36966f42604ab8435c8d1ab47a51e12d;hp=137b37010eeb68d92caedc1e1b818b934fbf44c9;hb=2c975fe48feaa8a78792510e5ef09c6f4cd9f655;hpb=3b8b76328cc151517a6525fabe48d3885e4c95c9 diff --git a/stat.c b/stat.c index 137b370..b9df032 100644 --- a/stat.c +++ b/stat.c @@ -24,7 +24,6 @@ #include #include -#include #include "gmqcc.h" @@ -56,6 +55,7 @@ static uint64_t stat_mem_allocated_total = 0; static uint64_t stat_mem_deallocated_total = 0; static uint64_t stat_mem_high = 0; static uint64_t stat_mem_peak = 0; +static uint64_t stat_mem_strdups = 0; static uint64_t stat_used_strdups = 0; static uint64_t stat_used_vectors = 0; static uint64_t stat_used_hashtables = 0; @@ -72,8 +72,8 @@ static stat_mem_block_t *stat_mem_block_root = NULL; */ static stat_size_table_t stat_size_new(void) { return (stat_size_table_t)memset( - mem_a(sizeof(stat_size_entry_t) * ST_SIZE), - 0, ST_SIZE * sizeof(stat_size_entry_t) + mem_a(sizeof(stat_size_entry_t*) * ST_SIZE), + 0, ST_SIZE * sizeof(stat_size_entry_t*) ); } @@ -224,6 +224,7 @@ char *stat_mem_strdup(const char *src, size_t line, const char *file, bool empty } stat_used_strdups ++; + stat_mem_strdups += len; return ptr; } @@ -275,22 +276,22 @@ typedef struct hash_node_t { * This is a patched version of the Murmur2 hashing function to use * a proper pre-mix and post-mix setup. Infact this is Murmur3 for * the most part just reinvented. - * + * * Murmur 2 contains an inner loop such as: * while (l >= 4) { * u32 k = *(u32*)d; * k *= m; * k ^= k >> r; * k *= m; - * + * * h *= m; * h ^= k; * d += 4; * l -= 4; * } - * + * * The two u32s that form the key are the same value x (pulled from data) - * this premix stage will be perform the same results for both. Unrolled + * this premix stage will perform the same results for both values. Unrolled * this produces just: * x *= m; * x ^= x >> r; @@ -300,18 +301,18 @@ typedef struct hash_node_t { * h ^= x; * h *= m; * h ^= x; - * - * This appears to be fine, except what happens when m == 1, well x + * + * This appears to be fine, except what happens when m == 1? well x * cancels out entierly, leaving just: * x ^= x >> r; * h ^= x; * h ^= x; - * + * * So all keys hash to the same value, but how often does m == 1? * well, it turns out testing x for all possible values yeilds only * 172,013,942 unique results instead of 2^32. So nearly ~4.6 bits * are cancelled out on average! - * + * * This means we have a 14.5% (rounded) chance of colliding more, which * results in another bucket/chain for the hashtable. * @@ -613,7 +614,7 @@ static void stat_dump_mem_contents(stat_mem_block_t *memory, uint16_t cols) { con_out("%c", (j >= memory->size) ? ' ' - : (isprint(((unsigned char*)(memory + 1))[j])) + : (util_isprint(((unsigned char*)(memory + 1))[j])) ? 0xFF & ((unsigned char*)(memory + 1)) [j] : '.' ); @@ -680,12 +681,14 @@ void stat_info() { uint64_t mem = 0; con_out("Memory Statistics:\n\ - Total vectors allocated: %llu\n\ - Total string duplicates: %llu\n\ - Total hashtables allocated: %llu\n\ - Total unique vector sizes: %llu\n", + Total vectors allocated: %llu\n\ + Total string duplicates: %llu\n\ + Total string duplicate memory: %f (MB)\n\ + Total hashtables allocated: %llu\n\ + Total unique vector sizes: %llu\n", stat_used_vectors, stat_used_strdups, + (float)(stat_mem_strdups) / 1048576.0f, stat_used_hashtables, stat_type_vectors );