16ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe/* 26ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * Generate/analyze pareto/zipf distributions to better understand 36ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * what an access pattern would look like. 46ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * 56ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * For instance, the following would generate a zipf distribution 66ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * with theta 1.2, using 100,000 values and split the reporting into 76ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * 20 buckets: 86ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * 96ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * t/genzipf zipf 1.2 100000 20 106ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe * 11f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe * Only the distribution type (zipf or pareto) and spread input need 12f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe * to be given, if not given defaults are used. 13f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe * 146ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe */ 156ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe#include <stdio.h> 166ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe#include <stdlib.h> 176ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe#include <fcntl.h> 186ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe#include <string.h> 19921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe#include <unistd.h> 206ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 216ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe#include "../lib/zipf.h" 22fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe#include "../flist.h" 23fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe#include "../hash.h" 246ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 25f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe#define DEF_NR 1000000 26f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe#define DEF_NR_OUTPUT 23 27f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe 28fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboestruct node { 29fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct flist_head list; 30fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe unsigned long long val; 31fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe unsigned long hits; 32fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe}; 33fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 34fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboestatic struct flist_head *hash; 35fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboestatic unsigned long hash_bits = 24; 36fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboestatic unsigned long hash_size = 1 << 24; 37fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 38921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboeenum { 39921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe TYPE_NONE = 0, 40921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe TYPE_ZIPF, 41921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe TYPE_PARETO, 42921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe}; 43921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic const char *dist_types[] = { "None", "Zipf", "Pareto" }; 44921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 45921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic int dist_type = TYPE_ZIPF; 46921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic unsigned long gb_size = 500; 47444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboestatic unsigned long block_size = 4096; 48921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic unsigned long output_nranges = DEF_NR_OUTPUT; 49444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboestatic double percentage; 50921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic double dist_val; 51355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fustatic int output_csv = 0; 52921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 53921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe#define DEF_ZIPF_VAL 1.2 54921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe#define DEF_PARETO_VAL 0.3 55921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 56fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboestatic struct node *hash_lookup(unsigned long long val) 57fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe{ 58fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct flist_head *l = &hash[hash_long(val, hash_bits)]; 59fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct flist_head *entry; 60fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct node *n; 61fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 62fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe flist_for_each(entry, l) { 63fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe n = flist_entry(entry, struct node, list); 64fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe if (n->val == val) 65fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe return n; 66fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe } 67fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 68fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe return NULL; 69fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe} 70fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 7124baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboestatic struct node *hash_insert(struct node *n, unsigned long long val) 72fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe{ 73fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct flist_head *l = &hash[hash_long(val, hash_bits)]; 74fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 75fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe n->val = val; 76fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe n->hits = 1; 77fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe flist_add_tail(&n->list, l); 7824baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe return n; 796ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe} 806ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 814e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboestatic void usage(void) 824e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe{ 834e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("genzipf: test zipf/pareto values for fio input\n"); 844e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-h\tThis help screen\n"); 854e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-p\tGenerate size of data set that are hit by this percentage\n"); 864e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-t\tDistribution type (zipf or pareto)\n"); 874e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-i\tDistribution algorithm input (zipf theta or pareto power)\n"); 884e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-b\tBlock size of a given range (in bytes)\n"); 894e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-g\tSize of data set (in gigabytes)\n"); 904e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-o\tNumber of output columns\n"); 914e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe printf("\t-c\tOutput ranges in CSV format\n"); 924e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe} 934e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe 94921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboestatic int parse_options(int argc, char *argv[]) 95921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe{ 964e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe const char *optstring = "t:g:i:o:b:p:ch"; 97921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe int c, dist_val_set = 0; 98921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 99921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe while ((c = getopt(argc, argv, optstring)) != -1) { 100921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe switch (c) { 1014e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe case 'h': 1024e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe usage(); 1034e98a45014737dc4f35d0ca599e4d1ccb4ef3c9bJens Axboe return 1; 104444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe case 'p': 105444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe percentage = atof(optarg); 106444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe break; 107444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe case 'b': 108444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe block_size = strtoul(optarg, NULL, 10); 109444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe break; 110921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe case 't': 111921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (!strncmp(optarg, "zipf", 4)) 112921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_type = TYPE_ZIPF; 113921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe else if (!strncmp(optarg, "pareto", 6)) 114921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_type = TYPE_PARETO; 115921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe else { 116921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe printf("wrong dist type: %s\n", optarg); 117921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe return 1; 118921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 119921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe break; 120921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe case 'g': 121921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe gb_size = strtoul(optarg, NULL, 10); 122921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe break; 123921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe case 'i': 124921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_val = atof(optarg); 125921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_val_set = 1; 126921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe break; 127921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe case 'o': 128921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe output_nranges = strtoul(optarg, NULL, 10); 129921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe break; 130355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu case 'c': 131355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu output_csv = 1; 132355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu break; 133921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe default: 134921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe printf("bad option %c\n", c); 135921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe return 1; 136921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 137921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 138921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 139921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (dist_type == TYPE_PARETO) { 140921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if ((dist_val >= 1.00 || dist_val < 0.00)) { 141921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe printf("pareto input must be > 0.00 and < 1.00\n"); 142921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe return 1; 143921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 144921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (!dist_val_set) 145921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_val = DEF_PARETO_VAL; 146921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } else if (dist_type == TYPE_ZIPF) { 147921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (dist_val == 1.0) { 148921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe printf("zipf input must be different than 1.0\n"); 149921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe return 1; 150921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 151921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (!dist_val_set) 152921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe dist_val = DEF_ZIPF_VAL; 153921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 154921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 155921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe return 0; 156921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe} 157921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 158444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboestruct output_sum { 159444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe double output; 160444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe unsigned int nranges; 161444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe}; 162444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe 16324baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboestatic int node_cmp(const void *p1, const void *p2) 16424baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe{ 16524baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe const struct node *n1 = p1; 16624baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe const struct node *n2 = p2; 16724baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe 16824baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe return n2->hits - n1->hits; 16924baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe} 17024baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe 1716ff3885617d8281bde48a9a19d34302add3fd017Jens Axboeint main(int argc, char *argv[]) 1726ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe{ 173fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe unsigned long offset; 17424baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe unsigned long i, j, k, nr_vals, cur_vals, interval, total_vals, nnodes; 175444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe unsigned long long nranges; 176444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe struct output_sum *output_sums; 17724baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe struct node *nodes; 178444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe double perc, perc_i; 1796ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe struct zipf_state zs; 1806ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 181921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (parse_options(argc, argv)) 1826ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe return 1; 1836ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 184355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if( !output_csv ) 185355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("Generating %s distribution with %f input and %lu GB size and %lu block_size.\n", dist_types[dist_type], dist_val, gb_size, block_size); 186444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe 187444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe nranges = gb_size * 1024 * 1024 * 1024ULL; 188444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe nranges /= block_size; 189f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe 190921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (dist_type == TYPE_ZIPF) 191921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe zipf_init(&zs, nranges, dist_val, 1); 1926ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe else 193921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe pareto_init(&zs, nranges, dist_val, 1); 1946ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 195c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe hash_bits = 0; 196c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe hash_size = nranges; 197c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe while ((hash_size >>= 1) != 0) 198c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe hash_bits++; 199c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe 200c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe hash_size = 1 << hash_bits; 201c71224e777dc07706148df6310f5a7bdca67a65cJens Axboe 202fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe hash = malloc(hash_size * sizeof(struct flist_head)); 203fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe for (i = 0; i < hash_size; i++) 204fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe INIT_FLIST_HEAD(&hash[i]); 205fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 20624baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe nodes = malloc(nranges * sizeof(struct node)); 20724baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe 20824baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe for (nr_vals = i = j = 0; i < nranges; i++) { 209fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe struct node *n; 2106ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 211921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe if (dist_type == TYPE_ZIPF) 212fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe offset = zipf_next(&zs); 2136ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe else 214fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe offset = pareto_next(&zs); 215fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe 216fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe n = hash_lookup(offset); 217fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe if (n) 218fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe n->hits++; 21924baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe else { 22024baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe hash_insert(&nodes[j], offset); 22124baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe j++; 22224baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe } 2236ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 2246ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe nr_vals++; 2256ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe } 2266ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 22724baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe qsort(nodes, j, sizeof(struct node), node_cmp); 22824baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe nnodes = j; 22924baa4c70c850d4c1703ae8f4e2b35fc5c5a57eaJens Axboe nr_vals = nnodes; 2306ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 231355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (output_csv) { 232355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("rank, count\n"); 233355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu for (k = 0; k < nnodes; k++) 234355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("%lu, %lu\n", k, nodes[k].hits); 235355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } else { 236355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu interval = (nr_vals + output_nranges - 1) / output_nranges; 237355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 238355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu output_sums = malloc(output_nranges * sizeof(struct output_sum)); 239355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu for (i = 0; i < output_nranges; i++) { 240355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu output_sums[i].output = 0.0; 241355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu output_sums[i].nranges = 1; 242444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe } 2436ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 244355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu total_vals = i = j = cur_vals = 0; 245355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 246355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu for (k = 0; k < nnodes; k++) { 247355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu struct output_sum *os = &output_sums[j]; 248355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu struct node *node = &nodes[k]; 249355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 250355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (i >= interval) { 251355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu os->output = 252355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu (double)(cur_vals + 1) / (double)nranges; 253355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu os->output *= 100.0; 254355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu j++; 255355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu cur_vals = node->hits; 256355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu interval += 257355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu (nr_vals + output_nranges - 258355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 1) / output_nranges; 259355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } else { 260355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu cur_vals += node->hits; 261355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu os->nranges += node->hits; 262355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } 263444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe 264355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu i++; 265355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu total_vals += node->hits; 266355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 267355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (percentage) { 268355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu unsigned long blocks = 269355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu percentage * nranges / 100; 270355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 271355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (total_vals >= blocks) { 272355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu double cs = 273355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu i * block_size / (1024 * 1024); 274355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu char p = 'M'; 275355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 276355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (cs > 1024.0) { 277355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu cs /= 1024.0; 278355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu p = 'G'; 279355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } 280355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (cs > 1024.0) { 281355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu cs /= 1024.0; 282355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu p = 'T'; 283355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } 284355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 285355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("%.2f%% of hits satisfied in %.3f%cB of cache\n", percentage, cs, p); 286355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu percentage = 0.0; 287444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe } 288444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe } 289444256eaf4f0ffdc4cacef37873d58f2a65bf8e6Jens Axboe } 2906ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 291355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu perc_i = 100.0 / (double)output_nranges; 292355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu perc = 0.0; 293921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 294355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("\n Rows Hits No Hits Size\n"); 295355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("--------------------------------------------------------\n"); 296355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu for (i = 0; i < j; i++) { 297355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu struct output_sum *os = &output_sums[i]; 298355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu double gb = (double)os->nranges * block_size / 1024.0; 299355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu char p = 'K'; 300921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 301355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (gb > 1024.0) { 302355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu p = 'M'; 303355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu gb /= 1024.0; 304355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } 305355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu if (gb > 1024.0) { 306355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu p = 'G'; 307355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu gb /= 1024.0; 308355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu } 309355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu 310355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu perc += perc_i; 311355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu printf("%s %6.2f%%\t%6.2f%%\t\t%8u\t%6.2f%c\n", 312355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu i ? "|->" : "Top", perc, os->output, os->nranges, 313355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu gb, p); 314921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe } 315921d17ba00f6fa106f558ea285d1d503f3a41369Jens Axboe 316355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu free(output_sums); 317f880b1f60dcfb278ab00e6b20994072b04dfd5afJens Axboe } 3186ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe 319fd6f237d84f0ab32c80e20184392918bbd91376cJens Axboe free(hash); 320355934b7ed82d13a5bfc043e2243013fd1e4e5bdVincent Kang Fu free(nodes); 3216ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe return 0; 3226ff3885617d8281bde48a9a19d34302add3fd017Jens Axboe} 323