1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2025-02-02 12:52:53 +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 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <memory.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -31,9 +32,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define panic(args...) \ #define panic(args...) \
do { fprintf (stderr, args); exit (-1); } while (0) do { fprintf (stderr, args); exit (-1); } while (0)
long dummy;
static long iterations = 10000; static long iterations = 10000;
static int maxlevel = 100; static int maxlevel = 100;
#define MB (1024*1024)
static char big[128*MB];
static inline double static inline double
gettime (void) gettime (void)
{ {
@ -44,20 +51,18 @@ gettime (void)
} }
static int 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_cursor_t cursor;
unw_context_t uc; unw_context_t uc;
int ret, level = 0; int ret, level = 0;
start = gettime ();
unw_getcontext (&uc); unw_getcontext (&uc);
if (unw_init_local (&cursor, &uc) < 0) if (unw_init_local (&cursor, &uc) < 0)
panic ("unw_init_local() failed\n"); panic ("unw_init_local() failed\n");
mid = gettime (); start = gettime ();
do do
{ {
@ -74,56 +79,99 @@ measure_unwind (int maxlevel, double *init, double *step)
panic ("Unwound only %d levels, expected at least %d levels", panic ("Unwound only %d levels, expected at least %d levels",
level, maxlevel); level, maxlevel);
*init = mid - start; *step = (stop - start) / (double) level;
*step = (stop - mid) / (double) level;
return 0; return 0;
} }
static int static int
f1 (int level, int maxlevel, double *init, double *step) f1 (int level, int maxlevel, double *step)
{ {
if (level == maxlevel) if (level == maxlevel)
return measure_unwind (maxlevel, init, step); return measure_unwind (maxlevel, step);
else else
/* defeat last-call/sibcall optimization */ /* defeat last-call/sibcall optimization */
return f1 (level + 1, maxlevel, init, step) + level; return f1 (level + 1, maxlevel, step) + level;
} }
static void static void
doit (const char *label) doit (const char *label)
{ {
double init, step, min_init, first_init, min_step, first_step; double step, min_step, first_step, sum_step;
double sum_init, sum_step;
int i; int i;
sum_init = sum_step = first_init = first_step = 0.0; sum_step = first_step = 0.0;
min_init = min_step = 1e99; min_step = 1e99;
for (i = 0; i < iterations; ++i) for (i = 0; i < iterations; ++i)
{ {
f1 (0, maxlevel, &init, &step); f1 (0, maxlevel, &step);
sum_init += init;
sum_step += step; sum_step += step;
if (init < min_init)
min_init = init;
if (step < min_step) if (step < min_step)
min_step = step; min_step = step;
if (i == 0) if (i == 0)
{
first_init = init;
first_step = step; first_step = step;
} }
} printf ("%s: unw_step : 1st=%9.3f min=%9.3f avg=%9.3f nsec\n", label,
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,
1e9*first_step, 1e9*min_step, 1e9*sum_step/iterations); 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 int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -134,14 +182,16 @@ main (int argc, char **argv)
iterations = atol (argv[2]); iterations = atol (argv[2]);
} }
measure_init ();
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); 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); 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); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
doit ("Caching: per-thread"); doit ("per-thread cache");
return 0; return 0;
} }