1 /* GLIB sliced memory - fast threaded memory chunk allocator
2 * Copyright (C) 2005 Tim Janik
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base)))
24 static gdouble
parse_memsize (const gchar
*cstring
);
25 static void usage (void);
28 fill_memory (guint
**mem
,
33 for (j
= 0; j
< n
; j
++)
38 access_memory3 (guint
**mema
,
44 guint64 accu
= 0, i
, j
;
46 for (i
= 0; i
< repeats
; i
++)
48 for (j
= 1; j
< n
; j
+= 2)
49 memd
[j
][o
] = mema
[j
][o
] + memb
[j
][o
];
51 for (i
= 0; i
< repeats
; i
++)
52 for (j
= 0; j
< n
; j
++)
58 touch_mem (guint64 block_size
,
62 guint64 j
, accu
, n
= n_blocks
;
66 guint
**mema
= g_new (guint
*, n
);
67 for (j
= 0; j
< n
; j
++)
68 mema
[j
] = g_slice_alloc (block_size
);
69 memb
= g_new (guint
*, n
);
70 for (j
= 0; j
< n
; j
++)
71 memb
[j
] = g_slice_alloc (block_size
);
72 memc
= g_new (guint
*, n
);
73 for (j
= 0; j
< n
; j
++)
74 memc
[j
] = g_slice_alloc (block_size
);
76 timer
= g_timer_new();
77 fill_memory (mema
, n
, 2);
78 fill_memory (memb
, n
, 3);
79 fill_memory (memc
, n
, 4);
80 access_memory3 (mema
, memb
, memc
, n
, 3);
81 g_timer_start (timer
);
82 accu
= access_memory3 (mema
, memb
, memc
, n
, repeats
);
85 g_print ("Access-time = %fs\n", g_timer_elapsed (timer
, NULL
));
86 g_assert (accu
/ repeats
== (2 + 3) * n
/ 2 + 4 * n
/ 2);
88 for (j
= 0; j
< n
; j
++)
90 g_slice_free1 (block_size
, mema
[j
]);
91 g_slice_free1 (block_size
, memb
[j
]);
92 g_slice_free1 (block_size
, memc
[j
]);
94 g_timer_destroy (timer
);
103 g_print ("Usage: slice-color <block-size> [memory-size] [repeats] [colorization]\n");
110 guint64 block_size
= 512, area_size
= 1024 * 1024, n_blocks
, repeats
= 1000000;
113 block_size
= parse_memsize (argv
[1]);
120 area_size
= parse_memsize (argv
[2]);
122 repeats
= parse_memsize (argv
[3]);
124 g_slice_set_config (G_SLICE_CONFIG_COLOR_INCREMENT
, parse_memsize (argv
[4]));
126 /* figure number of blocks from block and area size.
127 * divide area by 3 because touch_mem() allocates 3 areas
129 n_blocks
= area_size
/ 3 / ALIGN (block_size
, sizeof (gsize
) * 2);
131 /* basic sanity checks */
132 if (!block_size
|| !n_blocks
|| block_size
>= area_size
)
134 g_printerr ("Invalid arguments: block-size=%" G_GUINT64_FORMAT
" memory-size=%" G_GUINT64_FORMAT
"\n", block_size
, area_size
);
139 g_printerr ("Will allocate and touch %" G_GUINT64_FORMAT
" blocks of %" G_GUINT64_FORMAT
" bytes (= %" G_GUINT64_FORMAT
" bytes) %" G_GUINT64_FORMAT
" times with color increment: 0x%08" G_GINT64_MODIFIER
"x\n",
140 n_blocks
, block_size
, n_blocks
* block_size
, repeats
,
141 (guint64
)g_slice_get_config (G_SLICE_CONFIG_COLOR_INCREMENT
));
143 touch_mem (block_size
, n_blocks
, repeats
);
149 parse_memsize (const gchar
*cstring
)
151 gchar
*mem
= g_strdup (cstring
);
152 gchar
*string
= g_strstrip (mem
);
153 guint l
= strlen (string
);
158 switch (l
? string
[l
- 1] : 0)
160 case 'k': f
= 1000; break;
161 case 'K': f
= 1024; break;
162 case 'm': f
= 1000000; break;
163 case 'M': f
= 1024 * 1024; break;
164 case 'g': f
= 1000000000; break;
165 case 'G': f
= 1024 * 1024 * 1024; break;
169 msize
= g_ascii_strtod (string
, &derr
);
173 g_printerr ("failed to parse number at: %s\n", derr
);