diff --git a/kernel-shark/src/libkshark.c b/kernel-shark/src/libkshark.c index 4201fa02..f8f032e0 100644 --- a/kernel-shark/src/libkshark.c +++ b/kernel-shark/src/libkshark.c @@ -252,19 +252,19 @@ void kshark_free(struct kshark_context *kshark_ctx) free(kshark_ctx); } -static inline uint8_t knuth_hash(uint32_t val) +static inline uint32_t knuth_hash(uint32_t val) { /* - * Small table hashing function adapted from Donald E. Knuth's 32 bit + * Hashing function adapted from Donald E. Knuth's 32 bit * multiplicative hash. See The Art of Computer Programming (TAOCP). * Multiplication by the Prime number, closest to the golden ratio of - * 2^8. + * 2^32. */ - return UINT8_C(val) * UINT8_C(157); + return val * UINT32_C(2654435761); } static struct kshark_task_list * -kshark_find_task(struct kshark_context *kshark_ctx, uint8_t key, int pid) +kshark_find_task(struct kshark_context *kshark_ctx, uint32_t key, int pid) { struct kshark_task_list *list; @@ -276,13 +276,20 @@ kshark_find_task(struct kshark_context *kshark_ctx, uint8_t key, int pid) return NULL; } +static int hash_list[KS_TASK_HASH_SIZE]; + static struct kshark_task_list * kshark_add_task(struct kshark_context *kshark_ctx, int pid) { struct kshark_task_list *list; - uint8_t key; + uint32_t key; key = knuth_hash(pid); +// key += key >> KS_TASK_HASH_SHIFT; + key &= (1 << KS_TASK_HASH_SHIFT) - 1; + + hash_list[key]++; + list = kshark_find_task(kshark_ctx, key, pid); if (list) return list; @@ -680,6 +687,30 @@ static void free_rec_list(struct rec_list **rec_list, int n_cpus, free(rec_list); } +static void print_hash(void) +{ + int min = -1, max = -1; + int total = 0, avg, std = 0; + int i; + + for (i = 0; i < KS_TASK_HASH_SIZE; i++) { + if (min < 0 || hash_list[i] < min) + min = hash_list[i]; + if (max < 0 || hash_list[i] > max) + max = hash_list[i]; + total += hash_list[i]; + } + avg = total / KS_TASK_HASH_SIZE; + for (i = 0; i < KS_TASK_HASH_SIZE; i++) { + int diff = hash_list[i] - avg; + + std += diff * diff; + } + std /= KS_TASK_HASH_SIZE - 1; + printf("max=%d min=%d total=%d avg=%d std2=%d\n", + max, min, total, avg, std); +} + static ssize_t get_records(struct kshark_context *kshark_ctx, struct rec_list ***rec_list, enum rec_type type) { @@ -793,6 +824,7 @@ static ssize_t get_records(struct kshark_context *kshark_ctx, total += count; } + print_hash(); *rec_list = cpu_list; return total; diff --git a/kernel-shark/src/libkshark.h b/kernel-shark/src/libkshark.h index 04e9cbfc..3407db19 100644 --- a/kernel-shark/src/libkshark.h +++ b/kernel-shark/src/libkshark.h @@ -72,7 +72,8 @@ struct kshark_entry { }; /** Size of the task's hash table. */ -#define KS_TASK_HASH_SIZE 256 +#define KS_TASK_HASH_SHIFT 16 +#define KS_TASK_HASH_SIZE (1 << KS_TASK_HASH_SHIFT) /** Linked list of tasks. */ struct kshark_task_list {