1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2025-01-23 00:30:29 +01:00

Include <memory.h>.

(MB): New macro.
(big): New array.
(measure_unwind): Don't try to measure "init" step---it's too fast.
(f1): Likewise.
(doit): Likewise.
(sum): New function.
(measure_init): Measure unw_getcontext() and unw_local_init() here.
(main): Call measure_init(), adjust labels for doit() calls.

(Logical change 1.190)
This commit is contained in:
mostang.com!davidm 2004-03-27 09:25:58 +00:00
parent a77f17b0b7
commit 96c6250626

View file

@ -21,6 +21,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
@ -31,9 +32,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define panic(args...) \
do { fprintf (stderr, args); exit (-1); } while (0)
long dummy;
static long iterations = 10000;
static int maxlevel = 100;
#define MB (1024*1024)
static char big[128*MB];
static inline double
gettime (void)
{
@ -44,20 +51,18 @@ gettime (void)
}
static int
measure_unwind (int maxlevel, double *init, double *step)
measure_unwind (int maxlevel, double *step)
{
double stop, mid, start;
double stop, start;
unw_cursor_t cursor;
unw_context_t uc;
int ret, level = 0;
start = gettime ();
unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0)
panic ("unw_init_local() failed\n");
mid = gettime ();
start = gettime ();
do
{
@ -74,56 +79,99 @@ measure_unwind (int maxlevel, double *init, double *step)
panic ("Unwound only %d levels, expected at least %d levels",
level, maxlevel);
*init = mid - start;
*step = (stop - mid) / (double) level;
*step = (stop - start) / (double) level;
return 0;
}
static int
f1 (int level, int maxlevel, double *init, double *step)
f1 (int level, int maxlevel, double *step)
{
if (level == maxlevel)
return measure_unwind (maxlevel, init, step);
return measure_unwind (maxlevel, step);
else
/* defeat last-call/sibcall optimization */
return f1 (level + 1, maxlevel, init, step) + level;
return f1 (level + 1, maxlevel, step) + level;
}
static void
doit (const char *label)
{
double init, step, min_init, first_init, min_step, first_step;
double sum_init, sum_step;
double step, min_step, first_step, sum_step;
int i;
sum_init = sum_step = first_init = first_step = 0.0;
min_init = min_step = 1e99;
sum_step = first_step = 0.0;
min_step = 1e99;
for (i = 0; i < iterations; ++i)
{
f1 (0, maxlevel, &init, &step);
f1 (0, maxlevel, &step);
sum_init += init;
sum_step += step;
if (init < min_init)
min_init = init;
if (step < min_step)
min_step = step;
if (i == 0)
{
first_init = init;
first_step = step;
}
}
printf ("%s:\n"
" unw_{getcontext+init_local}: 1st=%9.3f min=%9.3f avg=%9.3f nsec\n"
" unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n",
label,
1e9*first_init, 1e9*min_init, 1e9*sum_init/iterations,
printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label,
1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations);
}
static long
sum (char *buf, size_t size)
{
long s = 0;
size_t i;
for (i = 0; i < size; ++i)
s += *buf++;
return s;
}
static void
measure_init (void)
{
# define N 1000
double stop, start, getcontext_cold, getcontext_warm, init_cold, init_warm;
unw_cursor_t cursor[N];
unw_context_t uc[N];
int i;
/* Ensure memory is paged in but not in the cache: */
memset (cursor, 0, sizeof (cursor));
memset (uc, 0, sizeof (uc));
dummy = sum (big, sizeof (big));
start = gettime ();
for (i = 0; i < N; ++i)
unw_getcontext (&uc[i]);
stop = gettime ();
getcontext_cold = (stop - start) / N;
start = gettime ();
for (i = 0; i < N; ++i)
unw_init_local (&cursor[i], &uc[i]);
stop = gettime ();
init_cold = (stop - start) / N;
start = gettime ();
for (i = 0; i < N; ++i)
unw_getcontext (&uc[0]);
stop = gettime ();
getcontext_warm = (stop - start) / N;
start = gettime ();
for (i = 0; i < N; ++i)
unw_init_local (&cursor[0], &uc[0]);
stop = gettime ();
init_warm = (stop - start) / N;
printf ("unw_getcontext : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n",
1e9 * getcontext_cold, 1e9 * getcontext_warm);
printf ("unw_init_local : cold avg=%9.3f nsec, warm avg=%9.3f nsec\n",
1e9 * init_cold, 1e9 * init_warm);
}
int
main (int argc, char **argv)
{
@ -134,14 +182,16 @@ main (int argc, char **argv)
iterations = atol (argv[2]);
}
measure_init ();
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE);
doit ("Caching: none");
doit ("no cache ");
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
doit ("Caching: global");
doit ("global cache ");
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
doit ("Caching: per-thread");
doit ("per-thread cache");
return 0;
}