GNUnet  0.19.5
ibf_sim.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
29 #include "platform.h"
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 
34 #define MAX_IBF_DECODE 16
35 
36 /* report average over how many rounds? */
37 #define ROUNDS 100000
38 
39 /* enable one of the three below */
40 // simple fix
41 #define FIX1 0
42 // possibly slightly better fix for large IBF_DECODE values
43 #define FIX2 1
44 
45 // SIGCOMM algorithm
46 #define STRATA 0
47 
48 // print each value?
49 #define VERBOSE 0
50 // avoid assembly? (ASM is about 50% faster)
51 #define SLOW 0
52 
53 int
54 main (int argc, char **argv)
55 {
56  unsigned int round;
57  unsigned int buckets[31]; // max is 2^31 as 'random' returns only between 0 and 2^31
58  unsigned int i;
59  int j;
60  unsigned int r;
61  unsigned int ret;
62  unsigned long long total;
63  unsigned int want;
64  double predict;
65 
66  srandom (time (NULL));
67  total = 0;
68  want = atoi (argv[1]);
69  for (round = 0; round < ROUNDS; round++)
70  {
71  memset (buckets, 0, sizeof(buckets));
72  for (i = 0; i < want; i++)
73  {
74  /* FIXME: might want to use 'better' PRNG to avoid
75  PRNG-induced biases */
76  r = random ();
77  if (0 == r)
78  continue;
79 #if SLOW
80  for (j = 0; (j < 31) && (0 == (r & (1 << j))); j++)
81  ;
82 #else
83  /* use assembly / gcc */
84  j = __builtin_ffs (r) - 1;
85 #endif
86  buckets[j]++;
87  }
88  ret = 0;
89  predict = 0.0;
90  for (j = 31; j >= 0; j--)
91  {
92 #if FIX1
93  /* improved algorithm, for 1000 elements with IBF-DECODE 8, I
94  get 990/1000 elements on average over 1 million runs; key
95  idea being to stop short of the 'last' possible IBF as
96  otherwise a "lowball" per-chance would unduely influence the
97  result */if ((j > 0) &&
98  (buckets[j - 1] > MAX_IBF_DECODE))
99  {
100  ret *= (1 << (j + 1));
101  break;
102  }
103 #endif
104 #if FIX2
105  /* another improvement: don't just always cut off the last one,
106  but rather try to predict based on all previous values where
107  that "last" one is; additional prediction can only really
108  work if MAX_IBF_DECODE is sufficiently high */
109  if ((j > 0) &&
110  ((buckets[j - 1] > MAX_IBF_DECODE) ||
111  (predict > MAX_IBF_DECODE)))
112  {
113  ret *= (1 << (j + 1));
114  break;
115  }
116 #endif
117 #if STRATA
118  /* original algorithm, for 1000 elements with IBF-DECODE 8,
119  I get 920/1000 elements on average over 1 million runs */
120  if (buckets[j] > MAX_IBF_DECODE)
121  {
122  ret *= (1 << (j + 1));
123  break;
124  }
125 #endif
126  ret += buckets[j];
127  predict = (buckets[j] + 2.0 * predict) / 2.0;
128  }
129 #if VERBOSE
130  fprintf (stderr, "%u ", ret);
131 #endif
132  total += ret;
133  }
134  fprintf (stderr, "\n");
135  fprintf (stdout, "average %llu\n", total / ROUNDS);
136  return 0;
137 }
138 
139 
140 /* TODO: should calculate stddev of the results to also be able to
141  say something about the stability of the results, outside of
142  large-scale averages -- gaining 8% precision at the expense of
143  50% additional variance might not be worth it... */
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int main(int argc, char **argv)
Definition: ibf_sim.c:54
#define MAX_IBF_DECODE
Definition: ibf_sim.c:34
#define ROUNDS
Definition: ibf_sim.c:37