/** * @file dbusage.yap * @author VITOR SANTOS COSTA * @date Tue Nov 17 15:04:52 2015 * * @brief Useful statistics on memory usage * * */ :- module(dbusage, [ db_usage/0, db_static/0, db_static/1, db_dynamic/0, db_dynamic/1 ]). /** * @defgroup dbusage Memory Usage in Prolog Data-Base * @ingroup library @{ This library provides a set of utilities for studying memory usage in YAP. The following routines are available once included with the `use_module(library(dbusage))` command. */ /** @pred db_usage Give general overview of data-base usage in the system. */ db_usage :- statistics(heap,[HeapUsed,HeapFree]), statistics(local_stack,[GInU,FreeS]), statistics(global_stack,[SInU,_]), statistics(trail,[TInU,FreeT]), HeapUsedK is HeapUsed//1024, HeapFreeK is HeapFree//1024, StackSpace is (GInU+SInU+FreeS+TInU+FreeT)//1024, format(user_error, 'Heap Space = ~D KB (+ ~D KB free)~n',[HeapUsedK,HeapFreeK]), format(user_error, 'Stack Space = ~D KB~n',[StackSpace]), findall(p(Cls,CSz,ISz), (current_module(M), current_predicate(_,M:P), predicate_statistics(M:P,Cls,CSz,ISz)),LAll), sumall(LAll, TCls, TCSz, TISz), statistics(atoms,[AtomN,AtomS]), AtomSK is AtomS//1024, format(user_error, '~D Atoms taking ~D KB~n',[AtomN,AtomSK]), TSz is TCSz+TISz, TSzK is TSz//1024, TCSzK is TCSz//1024, TISzK is TISz//1024, format(user_error, 'Total User Code~n ~D clauses taking ~D KB~n ~D KB in clauses + ~D KB in indices~n', [TCls,TSzK,TCSzK,TISzK]), statistics(static_code,[SCl,SI,SI1,SI2,SI3]), SClK is SCl//1024, SIK is SI//1024, SI1K is SI1//1024, SI2K is SI2//1024, SI3K is SI3//1024, ST is SCl+SI, STK is ST//1024, format(user_error, 'Total Static code=~D KB~n ~D KB in clauses + ~D KB in indices (~D+~D+~D)~n', [STK,SClK,SIK,SI1K,SI2K,SI3K]), statistics(dynamic_code,[DCl,DI,DI1,DI2,DI3,DI4]), DClK is DCl//1024, DIK is DI//1024, DI1K is DI1//1024, DI2K is DI2//1024, DI3K is DI3//1024, DI4K is DI4//1024, DT is DCl+DI, DTK is DT//1024, format(user_error, 'Total Dynamic code=~D KB~n ~D KB in clauses + ~D KB in indices (~D+~D+~D+~D)~n', [DTK,DClK,DIK,DI1K,DI2K,DI3K,DI4K]), total_erased(DCls,DSZ,ICls,ISZ), (DCls =:= 0 -> true ; DSZK is DSZ//1024, format(user_error, ' ~D erased clauses not reclaimed (~D KB)~n',[DCls,DSZK]) ), (ICls =:= 0 -> true ; ISZK is ISZ//1024, format(user_error, ' ~D erased indices not reclaimed (~D KB)~n',[ICls,ISZK]) ), !. db_usage:- write(mem_dump_error),nl. /** @pred db_static List memory usage for every static predicate. */ db_static :- db_static(-1). /** @pred db_static(+ _Threshold_) List memory usage for every static predicate. Predicate must use more than _Threshold_ bytes. */ db_static(Min) :- setof(p(Sz,M:P,Cls,CSz,ISz), PN^(current_module(M), current_predicate(PN,M:P), \+ predicate_property(M:P,dynamic), predicate_statistics(M:P,Cls,CSz,ISz), Sz is (CSz+ISz), Sz > Min),All), format(user_error,' Static user code~n===========================~n',[]), display_preds(All). /** @pred db_dynamic List memory usage for every dynamic predicate. */ db_dynamic :- db_dynamic(-1). /** @pred db_dynamic(+ _Threshold_) List memory usage for every dynamic predicate. Predicate must use more than _Threshold_ bytes. */ db_dynamic(Min) :- setof(p(Sz,M:P,Cls,CSz,ISz,ECls,ECSz,EISz), PN^(current_module(M), current_predicate(PN,M:P), predicate_property(M:P,dynamic), predicate_statistics(M:P,Cls,CSz,ISz), predicate_erased_statistics(M:P,ECls,ECSz,EISz), Sz is (CSz+ISz+ECSz+EISz), Sz > Min), All), format(user_error,' Dynamic user code~n===========================~n',[]), display_dpreds(All). display_preds([]). display_preds([p(Sz,M:P,Cls,CSz,ISz)|_]) :- functor(P,A,N), KSz is Sz//1024, KCSz is CSz//1024, KISz is ISz//1024, (M = user -> Name = A/N ; Name = M:A/N), format(user_error,'~w~t~36+:~t~D~7+ clauses using~|~t~D~8+ KB (~D + ~D)~n',[Name,Cls,KSz,KCSz,KISz]), fail. display_preds([_|All]) :- display_preds(All). display_dpreds([]). display_dpreds([p(Sz,M:P,Cls,CSz,ISz,ECls,ECSz,EISz)|_]) :- functor(P,A,N), KSz is Sz//1024, KCSz is CSz//1024, KISz is ISz//1024, (M = user -> Name = A/N ; Name = M:A/N), format(user_error,'~w~t~36+:~t~D~7+ clauses using~|~t~D~8+ KB (~D + ~D)~n',[Name,Cls,KSz,KCSz,KISz]), (ECls =:= 0 -> true ; ECSzK is ECSz//1024, format(user_error,' ~D erased clauses: ~D KB~n',[ECls,ECSzK]) ), (EISz =:= 0 -> true ; EISzK is EISz//1024, format(user_error,' ~D KB erased indices~n',[EISzK]) ), fail. display_dpreds([_|All]) :- display_dpreds(All). sumall(LEDAll, TEDCls, TEDCSz, TEDISz) :- sumall(LEDAll, 0, TEDCls, 0, TEDCSz, 0, TEDISz). sumall([], TEDCls, TEDCls, TEDCSz, TEDCSz, TEDISz, TEDISz). sumall([p(Cls,CSz,ISz)|LEDAll], TEDCls0, TEDCls, TEDCSz0, TEDCSz, TEDISz0, TEDISz) :- TEDClsI is Cls+TEDCls0, TEDCSzI is CSz+TEDCSz0, TEDISzI is ISz+TEDISz0, sumall(LEDAll, TEDClsI, TEDCls, TEDCSzI, TEDCSz, TEDISzI, TEDISz). /** @} */