Top Banner
Mono’s New Profiler API
26

Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Oct 30, 2019

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Mono’sNewProfilerAPI

Page 2: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Motivation:ProblemswiththeoldAPI

• Impossibletoreconfigureprofilingoptionsatruntime

• Someinteractionsbetweenmultipleprofilerswereunclear

• ‘Allornothing’instrumentations,e.g.enter/leave

• CertainaspectsoftheAPIwereconfusingtousers

• Hadeventswhichwereneverfired

• Hadmanydeprecatedoroutrightbrokenfeaturesandevents

• Addingneweventstookmoreeffortthanitshould

Page 3: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

DesignGoals(I)

• Allprofilingfeaturesmustbetoggleableatruntime• Exceptforstuffthataffectscodegeneration• Reconfigurationoffeaturesshouldbeasyncsafe• Somefeaturesmuststillbeenabledatstartuptobeusedlater,butareenabledinalatent(i.e.idle)state

• Disabledoridlefeaturesmustbecheap• Examples:

• Wedon’twanttogatherGCrootsifnorootscallbackisinstalled• Managedallocatorsmustbeusableregardlessofprofilingoptions• Samplingthreadshouldbesleepingwhensamplingisinidlemode

Page 4: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

DesignGoals(II)• Reasonablyfutureproof

• Addinganeweventshouldbasicallybea2-linechange• Forfeaturesthatcurrentlymustberequestedatstartup,wemusthavetheabilitytomakethemavailableatruntimeinthefuturewithoutfundamentallychangingtheAPI• AfutureversionofMonomightsupportrecompilingmethodsforallocationprofiling,enter/leaveinstrumentation,codecoverage,etc

• Clearmigrationpathforexistingusers• IfyouwereusingafunctionintheoldAPI,thereshouldbeanobviousequivalentinthenewAPI• Exceptforbrokenordeprecatedstuff

• WerefusetoloadaprofilerusingtheoldAPIsouserswillbeawarethattheirmodulemustbeupdated

Page 5: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

OldvsNew:Statisticalsamplingvoid mono_profiler_startup (const char *desc){

MonoProfiler *prof = g_new0 (MonoProfiler, 1);

mono_profiler_install (prof, shutdown_cb);

mono_profiler_set_statistical_mode (MONO_PROFILER_STAT_MODE_PROCESS, 100);mono_profiler_install_statistical (sample_cb);mono_profiler_set_events (MONO_PROFILE_STATISTICAL);

}

void mono_profiler_init_test (const char *desc){

MonoProfiler *prof = g_new0 (MonoProfiler, 1);MonoProfilerHandle handle = mono_profiler_create (prof);

mono_profiler_enable_sampling (handle);mono_profiler_set_runtime_shutdown_end_callback (handle, shutdown_cb);mono_profiler_set_sample_hit_callback (handle, sample_cb);

if (!mono_profiler_set_sample_mode (handle, MONO_PROFILER_SAMPLE_MODE_PROCESS, 100))fprintf (stderr, “Warning: Another profiler controls sampling parameters.");

}

Page 6: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

OldvsNew:Thekeydifferences

• Ahandleisnowusedtoaltersettingsforaninstalledprofiler

• Eachkindofeventnowhasafunctiontosetacallback

• Usernolongerhastoseteventflags;thisisdoneinternally

• Thesamplingfeaturemustbeenabledatstartup

• Theprofilerwillknowifanotherprofilercontrolssampling• Whicheverprofilerenablessamplingfirstgetscontroloverparameters

• Theentrypointsymbolnameforprofilermoduleshaschanged

Page 7: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

NewFeature:Dynamicreconfiguration

• Almostallprofilingfeaturescannowbereconfiguredatruntime• Eventcallbackscanbesetorunsetatanypoint

• Ifacallbackwassetatstartupandislaterunset,theruntimewon’twastetimecollectingthedataforthatcallback,justasifitwasn’tsetinthefirstplace

• Changingcallbacksisinherentlyracy;threadBmightstillraiseaneventeventhoughthreadAjustunsetthecallback

• Samplingmode(none,processtime,realtime)andsamplingfrequency(Hz)canbechangedbythecontrollingprofiler

Page 8: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

NewFeature:Enter/leavefilters

• Similartocodecoveragefilters

• Allowsaprofilertodecidewhichmethodstoinstrument• Candecidewhethertoinstrumenttheprologue,epilogue,orboth

• Candistinguishbetweennormalmethodexits,exceptionalexits,andtailcalls

• Ifanyprofilerwantsamethodinstrumented,itwillhappen,evenifothersdidn’trequestit,soaprofilershouldbepreparedtodealwiththis

• Cansignificantlyreducetheperformanceimpactofenter/leaveinstrumentationdependingontheusecase

Page 9: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

NewFeature:Callcontextintrospection

• Anextensionofenter/leaveinstrumentation

• Allowsenter/leavecallbackstoaccessthestackframeoftheinstrumentedmethod• Canaccessthethis reference,arguments,locals,andthereturnvalue

• Returnvalueunavailablefortailcalls(i.e.CILtail. prefixandjmp opcode)

• Stackframeaccessedbyusingsamedebuginfousedbythedebuggeragent

• Enablesarbitraryinstrumentationofwell-knownmethodsinthebaseclasslibrary• Profilingofnetworking,threadpool,reflection,etcusage

Page 10: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

NewFeature:Instrumentedmanagedallocators(I)

• Managedallocatorscannowbeusedwhenprofiling

• Donewithaprofilervariantofthemanagedallocator• Checksthenumberofinstalledallocationeventcallbacksinan‘unlikely’branchattheendoftheallocator

• CallsintotheprofilerAPIwiththeallocatedobjectifanon-zeroamountofcallbacksareinstalled

• Significantlyimprovesperformancewhenlatentallocationprofilingisenabled

Page 11: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

NewFeature:Instrumentedmanagedallocators(II)$ cat alloc.csclass Program {

static void Main () {for (var i = 0; i < 500000000; i++)

new object ();}

}$ mcs alloc.cs$ time MONO_GC_DEBUG=no-managed-allocator mono --profile=log alloc.exereal 0m30.507suser 0m30.141ssys 0m0.266s$ time mono --profile=log alloc.exereal 0m2.939suser 0m2.688ssys 0m0.234s

• Runningthelogprofilerwithallocationprofilinginlatentstateismuchfasterforallocation-heavyprograms

Page 12: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

RemovedFeature:Oldcodecoveragemode• Implementedinmono_arch_output_basic_block withineachbackend• Notimplementedformostarchitecturesasnobodydidtheportingeffort

• EntirelysupersededbytheIR-basedcodecoveragemode

• IfoneprofilerrequestedthismodeandanotherprofilerrequestedtheIR-basedmode,thingswouldbreakhorribly

Page 13: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

RemovedFeature:Callchainprofiling• Avariantofstatisticalsampling• Usedvariousfragilestrategiestocollectanativebacktraceonasamplehitsignal• Native:ManuallyunwindthestackbasedonaMonoContext

• Usedheuristicsandwasnotportableatall;onlyworkedonx86• glibc:Usethebacktrace function

• Notguaranteedtobesignalsafe,orevenproduceusefulresultsinasignalhandler• Managed:UnwindthestackbasedonaMonoContext andmono_find_jit_info• Lessfragilebutalsolessuseful;couldsimplyusemono_stack_walk_async_safe instead

• Willprobablyuselibunwindifweexplorethisfeatureagain

Page 14: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Eventdefinitions(I)

• Aneventisnowdefinedwithasinglelineinprofiler-events.h:...MONO_PROFILER_EVENT_2(gc_event, GCEvent, MonoProfilerGCEvent, event, uint32_t, generation)MONO_PROFILER_EVENT_1(gc_allocation, GCAllocation, MonoObject *, object)MONO_PROFILER_EVENT_2(gc_moves, GCMoves, MonoObject *const *, objects, uint64_t, count)...

• profiler-events.hisaparameterizedheader• Similartomini/mini-ops.h,metadata/icall-def.h• Includedinprofiler.h,profiler.c,profiler-private.htogeneratetheentireeventcallbackAPI

• Glorifiedmacrohack,butprettyconvenient

Page 15: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Eventdefinitions(II)

typedef void (*MonoProfilerGCAllocationCallback) (MonoProfiler *prof, MonoObject *object);

MONO_API void mono_profiler_set_gc_allocation_callback (MonoProfilerHandle handle,MonoProfilerGCAllocationCallback cb)

{update_callback (&handle->gc_allocation_cb, cb, &mono_profiler_state.gc_allocation_count);

}

void mono_profiler_raise_gc_allocation (MonoObject *object){

for (MonoProfilerHandle h = mono_profiler_state.profilers; h; h = h->next) {MonoProfilerGCAllocationCallback cb = h->gc_allocation_cb;if (cb)

cb (h->prof, object);}

}

• Examplecodegeneratedforthegc_allocation event:

Page 16: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Callbackregistration(I)

• Theruntimeneedsafastwaytodeterminewhetheritshouldraiseanevent,orformoreexpensiveevents,gathertheneededdata• WebasicallyneedareplacementforeventflagsintheoldAPI

• Butusersshouldnothavetobotherwiththisstuff

• Solution:Anatomiccounterforeachevent• Incrementedwhenweinstallanon-NULL callback,decrementedwhenweinstallaNULL callback• Notactuallythatsimple:Couldleadtounbalancedincrements/decrementsifaprofilerinstallsmorenon-NULL callbacksthanNULL callbacks

Page 17: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Callbackregistration(II)static voidupdate_callback (volatile void **location, void *new, volatile uint32_t *counter){

void *old;

do {old = InterlockedReadPointer (location);

} while (InterlockedCompareExchangePointer (location, new, old) != old);

if (old)InterlockedDecrement (counter);

if (new)InterlockedIncrement (counter);

}

• Ensuresthatthecounterreflectstheexactamountofinstalledcallbacks• Slightlyracy:NULL callbackcanbeinstalledwhilecounterisnon-zero

Page 18: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Raisingevents(I)#define MONO_PROFILER_ENABLED(name) \

G_UNLIKELY (mono_profiler_state.name ## _count)

#define MONO_PROFILER_RAISE(name, args) \do { \

if (MONO_PROFILER_ENABLED (name)) \mono_profiler_raise_ ## name args; \

} while (0)

• RuntimecodecanuseMONO_PROFILER_ENABLED explicitlywhengatheringdataforaneventisexpensive

• MostruntimecodeshoulduseMONO_PROFILER_RAISE since,forthevastmajorityofevents,thedataisreadilyavailable

Page 19: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Raisingevents(II)voidsgen_client_collecting_minor (SgenPointerQueue *fin_ready_queue, SgenPointerQueue *critical_fin_queue){

if (MONO_PROFILER_ENABLED (gc_roots))report_registered_roots ();

if (MONO_PROFILER_ENABLED (gc_roots))report_finalizer_roots (fin_ready_queue, critical_fin_queue);

}

static MonoObject *do_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error){

...

MONO_PROFILER_RAISE (method_begin_invoke, (method));

result = callbacks.runtime_invoke (method, obj, params, exc, error);

MONO_PROFILER_RAISE (method_end_invoke, (method));

...}

Page 20: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Statisticalsampling(I)

• Samplerthreadsendssignalstoalllivethreadsataconfiguredfrequency(Hz)basedonaconfiguredclock(processorrealtime)• ProcesstimenotsupportedonallOSs;fallsbacktorealtime• UsesrealtimesignalswhentheOSsupportsthem• Usesrealtimeschedulingwhenavailable(usuallyrequiresroot)• Skipsspecialthreads(e.g.toolsthreads,SGenworkerthreads)

• Signalhandlerraisesthesamplehitprofilereventwithinstructionpointerandsignalcontext• Profilercanthenusee.g.mono_stack_walk_async_safe

Page 21: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Statisticalsampling(II)

• Roomforimprovement• Weshouldexploremakingrealtimeschedulingworkwithoutroot

• OSXseemstoallowit,butit’scomplicated

• OSswithoutrealtimesignalsdropmanyofoursamplingsignals• E.g.OSXhasnosupportforsignalqueuing;justusesabitmask

• Onlyoneinstanceofeachsignalcanbeinflightatanygiventime• Thisresultsinmostsignalsgoingtothemainthread• Possiblesolutions:

• UseMachthreadsuspend/resumeAPIstodosampling(Appleplatformsonly)• Figureoutsomekindofreliableround-robinsignalstrategy(portable)

Page 22: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Instrumentedmanagedallocators

MONO_PROFILER_RAISE (gc_allocation, (obj));

• BasicallyaregularallocatorbutwiththeCILequivalentof:

• Theeventisraisedafterweexitthecriticalregionandjustbeforewereturntonormalmanagedcode• Eventcallbackscanexecutearbitrarycodewhichmighte.g.takealock

• WhenweloadanAOTimage,allallocatorwrapperswillberedirectedtotheinstrumentedvariantifallocationprofilingwasrequestedatstartup• Thisway,wedon’thavetodisablemanagedallocatorswhenwewanttodoallocationprofilingonaFullAOTtargetsuchasiOS

Page 23: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Enter/leaveinstrumentation• ImplementedasJITinternalcalls

• Enter:Emittedintheentrybasicblock• Leave:Emittedbeforeret,jmp,andtail.call instructions

• Callcontextsareallocatedonthestackandpassedtothecallback• IntheJIT:Filledoutbyaspecialfill_prof_call_ctx IRinstruction

• Copiesstackpointer,framepointer,andcallee-savedregisterstothecontext• Alsostoresanaddresstothereturnvalueforanepiloguecontext• Valuesareretrievedfromthestatestoredinthecallcontextbasedondebuginfo• NotsupportedintheLLVMbackend(sonowatchOSsupport)

• Intheinterpreter:WestoreapointertotheInterpFrame inthecallcontext• ValuesareretrievedfromtheInterpFrame;noneedfordebuginfo

Page 24: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Codecoverage(I)

• Acoverageinfostructureisallocatedforeachmethod• Containsaseriesofcoverageentries,whereeachentryconsistsofaCILoffsetandacoveragecounter

• Everybasicblockinthemethodisinstrumentedwithatinypieceofcodethatincrementsthecounterinthecoverageentrycorrespondingtothebasicblock’sCILoffset

• Aprofilerrequeststheresultsofcoverageinstrumentationonshutdown,wherewemapeachcoverageentrytoasourcecodelocationbasedondebuginfo

Page 25: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Implementation:Codecoverage(II)

• Roomforimprovement• WeembedtheaddressofthecounterdirectlyinIR,whichisincompatiblewithAOT• Inparticular,thismeanscoverageanalysisisunavailableoniOS,watchOS,etc

• WeallocateasmanycoverageentriesasthereareCILinstructionsinamethod,whichisquitewasteful

• Thefactthatabasicblockhasbeenentereddoesnotnecessarilymeanthattheentirebasicblockwillbeexecuted• ThisisbecausetheJITusesextendedbasicblocks,i.e.anyinstructioncanthrowanexceptionandthusexittheblock

Page 26: Mono's New Profiler API - xamarin.azureedge.nets New Profiler API.pdf · New Feature: Dynamic reconfiguration •Almost all profiling features can now be reconfigured at runtime •Event

Conclusion

• ThenewprofilerAPIhasamoreclearlydefinedAPIcontract,givesmorecontroltousers,andhaspavedthewayfornewfeaturesthatwouldbeverydifficulttoimplementintheoldAPI

• VeryeasytoevolvethenewAPI

• TheAPIisclosetohavingfeatureparitywiththeCLRAPI

• FirstandhopefullylasttimewebreakprofilerAPIcompatibility

• NewAPIshipsinMono5.6