Use statistical approach to approximate the max number of nodes per population
[userspace-rcu.git] / rcuja / testpop.c
CommitLineData
3d45251f
MD
1/*
2 * rcuja/testpop.c
3 *
4 * Userspace RCU library - RCU Judy Array population size test
5 *
6 * Copyright 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/*
24 * This program generates random populations, and shows the worse-case
25 * unbalance, as well as the distribution of unbalance encountered.
26 * Remember that the unbalance is the delta between the lowest and
27 * largest population. Therefore, to get the delta between the subclass
28 * size and the actual number of items, we need to divide the unbalance
29 * by the number of subclasses (by hand).
30 */
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <stdint.h>
35#include <time.h>
36#include <string.h>
37#include <limits.h>
38
39static int sel_pool_len = 50; /* default */
40static int nr_distrib = 2; /* default */
41//#define SEL_POOL_LEN 100
42//#define NR_POOLS 10000000ULL
43
44static uint8_t pool[256];
45static uint8_t nr_one[8];
46static uint8_t nr_2d_11[8][8];
47static uint8_t nr_2d_10[8][8];
48static int global_max_minunbalance = 0;
49
50static unsigned int unbalance_distrib[256];
51
52static
53uint8_t random_char(void)
54{
55 return (uint8_t) random();
56}
57
58static
59void print_pool(void)
60{
61 int i;
62
63 printf("pool: ");
64 for (i = 0; i < sel_pool_len; i++) {
65 printf("%d ", (int) pool[i]);
66 }
67 printf("\n");
68}
69
70static
71void gen_pool(void)
72{
73 uint8_t src_pool[256];
74 int i;
75 int nr_left = 256;
76
77 memset(pool, 0, sizeof(pool));
78 for (i = 0; i < 256; i++)
79 src_pool[i] = (uint8_t) i;
80 for (i = 0; i < sel_pool_len; i++) {
81 int sel;
82
83 sel = random_char() % nr_left;
84 pool[i] = src_pool[sel];
85 src_pool[sel] = src_pool[nr_left - 1];
86 nr_left--;
87 }
88}
89
90static
91void count_pool(void)
92{
93 int i;
94
95 memset(nr_one, 0, sizeof(nr_one));
96 memset(nr_2d_11, 0, sizeof(nr_2d_11));
97 memset(nr_2d_10, 0, sizeof(nr_2d_10));
98 for (i = 0; i < sel_pool_len; i++) {
99 if (nr_distrib == 2) {
100 int j;
101
102 for (j = 0; j < 8; j++) {
103 if (pool[i] & (1U << j))
104 nr_one[j]++;
105 }
106 }
107
108 if (nr_distrib == 4) {
109 int j, k;
110
111 for (j = 0; j < 8; j++) {
112 for (k = 0; k < j; k++) {
113 if ((pool[i] & (1U << j)) && (pool[i] & (1U << k))) {
114 nr_2d_11[j][k]++;
115 }
116 if ((pool[i] & (1U << j)) && !(pool[i] & (1U << k))) {
117 nr_2d_10[j][k]++;
118 }
119 }
120 }
121 }
122 }
123}
124
125static
126void print_count(void)
127{
128 int i;
129
130 printf("pool distribution:\n");
131
132 if (nr_distrib == 2) {
133 printf(" 0 1\n");
134 printf("----------\n");
135 for (i = 0; i < 8; i++) {
136 printf("%3d %3d\n",
137 sel_pool_len - nr_one[i], nr_one[i]);
138 }
139 }
140
141 if (nr_distrib == 4) {
142 /* TODO */
143 }
144 printf("\n");
145}
146
147static
148void stat_count(void)
149{
150 int minunbalance = INT_MAX;
151
152 if (nr_distrib == 2) {
153 int i;
154
155 for (i = 0; i < 8; i++) {
156 int diff;
157
158 diff = (int) nr_one[i] * 2 - sel_pool_len;
159 if (diff < 0)
160 diff = -diff;
161 if (diff < minunbalance) {
162 minunbalance = diff;
163 }
164 }
165 }
166
167 if (nr_distrib == 4) {
168 int j, k;
169
170 for (j = 0; j < 8; j++) {
171 for (k = 0; k < j; k++) {
172 int diff[2];
173
174 diff[0] = (int) nr_2d_11[j][k] * 4 - sel_pool_len;
175 if (diff[0] < 0)
176 diff[0] = -diff[0];
177
178 diff[1] = (int) nr_2d_10[j][k] * 4 - sel_pool_len;
179 if (diff[1] < 0)
180 diff[1] = -diff[1];
181 /* Get max linear array size */
182 if (diff[1] > diff[0])
183 diff[0] = diff[1];
184 if (diff[0] < minunbalance) {
185 minunbalance = diff[0];
186 }
187 }
188 }
189 }
190
191 if (minunbalance > global_max_minunbalance) {
192 global_max_minunbalance = minunbalance;
193 }
194 unbalance_distrib[minunbalance]++;
195}
196
197static
198void print_distrib(void)
199{
200 int i;
201 unsigned long long tot = 0;
202
203 for (i = 0; i < 256; i++) {
204 tot += unbalance_distrib[i];
205 }
206 if (tot == 0)
207 return;
208 printf("Distribution:\n");
209 for (i = 0; i < 256; i++) {
210 printf("(%u, %u, %llu%%) ",
211 i, unbalance_distrib[i],
212 100 * (unsigned long long) unbalance_distrib[i] / tot);
213 }
214 printf("\n");
215}
216
217static
218void print_stat(uint64_t i)
219{
220 printf("after %llu pools, global_max_minunbalance: %d\n",
221 (unsigned long long) i, global_max_minunbalance);
222 print_distrib();
223}
224
225int main(int argc, char **argv)
226{
227 uint64_t i = 0;
228
229 srandom(time(NULL));
230
231 if (argc > 1) {
232 sel_pool_len = atoi(argv[1]);
233 if (sel_pool_len > 256 || sel_pool_len < 1) {
234 printf("Wrong pool len\n");
235 return -1;
236 }
237 }
238 printf("pool len: %d\n", sel_pool_len);
239
240 if (argc > 2) {
241 nr_distrib = atoi(argv[2]);
242 if (nr_distrib > 256 || nr_distrib < 1) {
243 printf("Wrong number of distributions\n");
244 return -1;
245 }
246 }
247 printf("pool distributions: %d\n", nr_distrib);
248
249 if (nr_distrib != 2 && nr_distrib != 4) {
250 printf("Wrong number of distributions. Only 2 and 4 supported.\n");
251 return -1;
252 }
253
254 //for (i = 0; i < NR_POOLS; i++) {
255 while (1) {
256 gen_pool();
257 count_pool();
258 //print_pool();
259 //print_count();
260 stat_count();
261 if (!(i % 100000ULL))
262 print_stat(i);
263 i++;
264 }
265 print_stat(i);
266 print_distrib();
267
268 return 0;
269}
This page took 0.032191 seconds and 4 git commands to generate.