⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 benchmark.h

📁 OTP是开放电信平台的简称
💻 H
字号:
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifndef __BENCHMARK_H__#define __BENCHMARK_H__/* The define __BENCHMARK__ is the master switch to turn on and off * benchmarking. This will enable the benchmark-BIFs in hipe_bif1.c. * Documentation for the BIFs is in hipe_bif1.c, and that is where you * will find the information about how to accually get some data out * from these timers and counters. *//* #define __BENCHMARK__ */#ifdef __BENCHMARK__/* * The defines below enables different parts of the benchmaring. * Counters and timers that are disabled, always report zero in * the BIFs. *//* BM_TIMERS keeps track of the time spent in diferent parts of the * system. It only measures accual active time, not time spent in idle * mode. These timers requires hardware support.  For Linux, use the * package perfctr from www.csd.uu.se/~mikpe/linux/perfctr. If this * package is not specified when configuring the system * (--with-perfctr=PATH), the Solaris hrtime_t will be used. * To add new timers look below. */#define BM_TIMERS/* BM_COUNTERS count all kinds of events that occurs in the system. * Among other things it counts the number of messages, then number of * garbage collections, the number of processes spawned etc. * To add new counters look below. */#define BM_COUNTERS/* BM_MESSAGE_SIZES keeps a log of the size of all messages sent in * the system. This introduce an overhead in time for the shared heap * system since all message sizes have to be calculated at send. *//* #define BM_MESSAGE_SIZES *//* BM_HEAP_SIZES goes through all processes at garbage collection time * to sum their allocated and used heap sizes. In anything else than a * shared heap system, this will cost. *//* #define BM_HEAP_SIZES *//* BM_STATISTICS saves an entry in the file BM_STATISTICS_FILE. This * is done for each erlang node at exit time. *//* #define BM_STATISTICS */#endif /* __BENCHMARK__ */#ifdef BM_STATISTICS#  define BM_STATISTICS_FILE "/tmp/erlang_statistics.joppe.log"#endif /* BM_STATISTICS *//************ There are no more settings below this line *************//* * Maintenance and how to add new stuff is documented by the code * below ;-) */#ifdef BM_COUNTERS/********************************************************************* * To add new counters: * * Add the variable here AND in benchmark.c. Use the macro * BM_COUNT(var) in the code where you want to increase it. * */extern unsigned long long processes_busy;extern unsigned long long processes_spawned;extern unsigned long long messages_sent;extern unsigned long long messages_copied;extern unsigned long long messages_ego;extern unsigned long long minor_gc;extern unsigned long long major_gc;#ifdef HYBRIDextern unsigned long long minor_global_gc;extern unsigned long long major_global_gc;extern unsigned long long gc_in_copy;#ifdef INCREMENTALextern unsigned long long minor_gc_cycles;extern unsigned long long major_gc_cycles;extern unsigned long long minor_gc_stages;extern unsigned long long major_gc_stages;#endif#endif#define BM_COUNT(var) (var)++;#define BM_EGO_COUNT(send,rec) {     \    if ((send) == (rec))             \        BM_COUNT(messages_ego);      }#define BM_LAZY_COPY_START long long gcs = minor_global_gc + major_global_gc;#define BM_LAZY_COPY_STOP { gcs = (minor_global_gc + major_global_gc) - gcs; \    if (gcs > gc_in_copy) gc_in_copy = gcs; }#else /* !BM_COUNTERS */#  define BM_COUNT(var)#  define BM_EGO_COUNT(send,rec)#  define BM_LAZY_COPY_START#  define BM_LAZY_COPY_STOP#endif /* BM_COUNTERS */#ifdef BM_TIMERS/********************************************************************* * To add new timers: * * Add the variable below using the form extern BM_TIMER_T blah_time. * Also add them in benchmark.c using the macro NEW_TIMER(blah).  Use * the macro BM_SWAP_TIMER(from,blah) ... BM_SWAP_TIMER(blah,to) to * start and stop the new timer. Note, that you have to know what * timer is running at the place where you want to insert your new * timer to be able to stop and start (from,to) it. * * You can use the macros BM_STOP_TIMER(blah) and BM_START_TIMER(blah) * around code that should not be timed at all. As above, you have to * know what timer to start and stop. The system timer is running at * most places in the emulator. Only the garbage collector and the * message sending has its own timers at the moment. * * The timer_time used when stopping timers is the time it takes to * start and stop the timers, calculated in init_benchmarking(). If it * is not there, the time it takes to do this will accually be * substantial compared to some small times in the system we want to * meassure (send time in shared heap for instance). */#if (defined(__i386__) || defined(__x86_64__)) && USE_PERFCTR#include "libperfctr.h"#define BM_TIMER_T doubleextern struct vperfctr *system_clock;extern double cpu_khz;extern BM_TIMER_T start_time;#define BM_START_TIMER(t) start_time =                                        \                          (BM_TIMER_T)vperfctr_read_tsc(system_clock) /       \                          cpu_khz;#define BM_STOP_TIMER(t) do {                                                 \    BM_TIMER_T tmp = ((BM_TIMER_T)vperfctr_read_tsc(system_clock) / cpu_khz); \    tmp -= (start_time + timer_time);                                         \    t##_time += (tmp > 0 ? tmp : 0);                                          \} while(0)#define BM_TIME_PRINTER(str,time) do {                                 \    int min,sec,milli,micro;                                           \    BM_TIMER_T tmp = (time) * 1000;                                    \    micro = (uint)(tmp - ((int)(tmp / 1000)) * 1000);                  \    tmp /= 1000;                                                       \    milli = (uint)(tmp - ((int)(tmp / 1000)) * 1000);                  \    tmp /= 1000;                                                       \    sec = (uint)(tmp - ((int)(tmp / 60)) * 60);                        \    min = (uint)tmp / 60;                                              \    erts_fprintf(file,str": %d:%02d.%03d %03d\n",min,sec,milli,micro);  \} while(0)#else /* !USE_PERFCTR  (Assuming Solaris) */#define BM_TIMER_T hrtime_t#define BM_START_TIMER(t) system_clock = sys_gethrtime()#define BM_STOP_TIMER(t) do {                                        \    BM_TIMER_T tmp = (sys_gethrtime() - system_clock) - timer_time;  \    t##_time += (tmp > 0 ? tmp : 0);                                 \} while(0)#define BM_TIME_PRINTER(str,time) do {                               \    int min,sec,milli,micro;                                         \    BM_TIMER_T tmp;                                                  \    tmp = (time) / 1000;                                             \    micro = tmp % 1000;                                              \    tmp /= 1000;                                                     \    milli = tmp % 1000;                                              \    tmp /= 1000;                                                     \    sec = tmp % 60;                                                  \    min = tmp / 60;                                                  \    erts_fprintf(file,str": %d:%02d.%03d %03d\n",min,sec,milli,micro);  \} while(0)extern BM_TIMER_T system_clock;#endif /* USE_PERFCTR */extern BM_TIMER_T timer_time;extern BM_TIMER_T system_time;extern BM_TIMER_T gc_time;extern BM_TIMER_T minor_gc_time;extern BM_TIMER_T major_gc_time;extern BM_TIMER_T minor_global_gc_time;extern BM_TIMER_T major_global_gc_time;extern BM_TIMER_T send_time;extern BM_TIMER_T copy_time;extern BM_TIMER_T size_time;extern BM_TIMER_T max_minor_time;extern BM_TIMER_T max_major_time;extern BM_TIMER_T max_global_minor_time;extern BM_TIMER_T max_global_major_time;extern BM_TIMER_T misc0_time;extern BM_TIMER_T misc1_time;extern BM_TIMER_T misc2_time;#define MAX_PAUSE_TIME 500000extern unsigned long local_pause_times[MAX_PAUSE_TIME];extern unsigned long pause_times[MAX_PAUSE_TIME];extern unsigned long pause_times_old[MAX_PAUSE_TIME];#define MMU_INTERVAL 5  /* milli seconds */extern BM_TIMER_T mmu_counter;extern BM_TIMER_T mmu;#define BM_NEW_TIMER(t) BM_TIMER_T t##_time = 0;#define BM_RESET_TIMER(t) t##_time = 0;#define BM_SWAP_TIMER(t1,t2) do { BM_STOP_TIMER(t1); BM_START_TIMER(t2); } while(0)#define BM_MMU_INIT() do {                                              \    BM_TIMER_T gc = gc_time;                                            \    while (gc > 0) {                                                    \        if (gc > MMU_INTERVAL) {                                        \            gc -= MMU_INTERVAL - mmu_counter;                           \            erts_printf("%d\n",(int)((mmu / MMU_INTERVAL) * 100));      \            mmu_counter = 0; mmu = 0;                                   \        } else {                                                        \            mmu_counter += gc;                                          \            if (mmu_counter >= MMU_INTERVAL) {                          \                mmu_counter -= MMU_INTERVAL;                            \                erts_printf("%d\n",(int)((mmu / MMU_INTERVAL) * 100));  \                mmu = 0;                                                \            }                                                           \            gc = 0;                                                     \        }                                                               \    }                                                                   \    BM_RESET_TIMER(system);                                             \    BM_RESET_TIMER(send);                                               \    BM_RESET_TIMER(copy);                                               \    BM_RESET_TIMER(size);                                               \} while(0)#define BM_MMU_READ() do {                                              \    BM_TIMER_T mut = system_time + send_time + copy_time + size_time;   \    while (mut > 0) {                                                   \        if (mut > MMU_INTERVAL) {                                       \            BM_TIMER_T tmp = MMU_INTERVAL - mmu_counter;                \            mmu += tmp; mut -= tmp;                                     \            erts_printf("%d\n",(int)((mmu / MMU_INTERVAL) * 100));      \            mmu_counter = 0; mmu = 0;                                   \        } else {                                                        \            mmu_counter += mut; mmu += mut;                             \            if (mmu_counter >= MMU_INTERVAL) {                          \                mmu_counter -= MMU_INTERVAL;                            \                mmu -= mmu_counter;                                     \                erts_printf("%d\n",(int)((mmu / MMU_INTERVAL) * 100));  \                mmu = mmu_counter;                                      \            }                                                           \            mut = 0;                                                    \        }                                                               \    }                                                                   \} while(0)#else /* !BM_TIMERS */#  define BM_NEW_TIMER(t)#  define BM_START_TIMER(t)#  define BM_STOP_TIMER(t)#  define BM_RESET_TIMER(t)#  define BM_SWAP_TIMER(t1,t2)#  define BM_TIME_PRINTER(str,time)#  define BM_MMU_INIT()#  define BM_MMU_READ()#endif /* BM_TIMERS */#ifdef BM_HEAP_SIZESextern unsigned long long max_used_heap;extern unsigned long long max_allocated_heap;extern unsigned long long max_used_global_heap;extern unsigned long long max_allocated_global_heap;#endif /* BM_HEAP_SIZES */#ifdef BM_MESSAGE_SIZESextern unsigned long long words_sent;extern unsigned long long words_copied;extern unsigned long long words_prealloc;extern unsigned long long message_sizes[1000];#define BM_MESSAGE_COPIED(size) { \    words_copied += size;         \    BM_COUNT(messages_copied);    }#define BM_PREALLOC_DATA(size) { \    words_prealloc += size;      }#define BM_MESSAGE(mess,send,rec) {  \    Uint msize = size_object(mess);  \    words_sent += msize;             \    if (msize < 1000)                \        message_sizes[msize]++;      \    else                             \        message_sizes[999]++;        \    BM_EGO_COUNT(send,rec);          \    BM_COUNT(messages_sent);         }#else /* !BM_MESSAGE_SIZES */#define BM_MESSAGE_COPIED(size) BM_COUNT(messages_copied);#define BM_PREALLOC_DATA(size)#define BM_MESSAGE(mess,send,rec) {  \    BM_EGO_COUNT(send,rec);          \    BM_COUNT(messages_sent);         }#endif /* BM_MESSAGE_SIZES */void init_benchmarking(void);void save_statistics(void);#endif /* _BENCHMARK_H_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -