Good Evening,

I looked into the excessive calls to _gst_reset_inline_caches. They
are mostly due calls to _gst_invalidate_method_cache and are done in
case of:


1.) Creating a new call-in process (in interp.c). This looks wrong. How
  should a new process change the look-up of a method?

2.) Installing a new method.

3.) VMpr_Behavior_flushCache. E.g. in gst-browser when selecting a category
  the following is executed:

(ip 52)[] in MethodDictionary>>#at:put:
(ip 30)[] in Semaphore>>#critical:
(ip 6)<unwind> BlockClosure>>#ensure:
(ip 8)Semaphore>>#critical:
(ip 8)MethodDictionary>>#at:put:
(ip 10)MethodDictionary(LookupTable)>>#add:
(ip 12)[] in Dictionary>>#select:
(ip 8)[] in LookupTable>>#associationsDo:
(ip 32)MethodDictionary(LookupTable)>>#keysAndValuesDo:
(ip 8)MethodDictionary(LookupTable)>>#associationsDo:
(ip 20)MethodDictionary(Dictionary)>>#select:
(ip 28)GtkMethodWidget>>#category:
(ip 10)GtkMethodWidget>>#class:withCategory:
(ip 12)GtkClassBrowserWidget>>#updateInstanceSideMethodCategory:
(ip 14)CategoryState>>#updateBrowser:
(ip 8)GtkClassBrowserWidget>>#state:
(ip 6)[] in GtkClassBrowserWidget>>#updateState:
(ip 8)[] in GtkClassBrowserWidget>>#checkCodeWidgetAndUpdate:
(ip 24)GtkClassBrowserWidget>>#saveCodeOr:
(ip 8)GtkClassBrowserWidget>>#checkCodeWidgetAndUpdate:
(ip 14)GtkClassBrowserWidget>>#updateState:
(ip 12)GtkClassBrowserWidget>>#onInstanceSideCategoryChanged


Starting gst-browser with some instrumentation gives output like this:

WALKED 35333 ICs.. 35331 cold diff 2
WALKED 35333 ICs.. 35268 cold diff 65

...

showing that the caches are mostly flushed twice. When doing a

  3+3 CTRL-P

a.) WALKED 84729 ICs.. 84129 cold diff 600
b.) WALKED 84729 ICs.. 84727 cold diff 2
c.) WALKED 84729 ICs.. 84656 cold diff 73

a.) 
(ip 52)[] in MethodDictionary>>#at:put:
(ip 30)[] in Semaphore>>#critical:

b.)
#1  0xb7f74625 in _gst_invalidate_method_cache () at interp.c:2363
#2  0xb7f1ddb9 in install_method (methodOOP=methodOOP@entry=0x40856308, 
classOOP=0x406306f0)
    at comp.c:2556

c.) 
(ip 38)[] in MethodDictionary>>#removeKey:ifAbsent:
(ip 30)[] in Semaphore>>#critical:
(ip 6)<unwind> BlockClosure>>#ensure:
(ip 8)Semaphore>>#critical:
(ip 6)MethodDictionary>>#removeKey:ifAbsent:
(ip 34)Behavior>>#removeSelector:ifAbsent:
(ip 38)GtkWorkspaceWidget(GtkTextWidget)>>#doWithoutForkIt:



Sorry. A lot of facts now some judgement and proposals.


Removing of calls:
1.) I think we can safely remove the flush from the call-in process
creation. This code has been there since the initial import.

2.) I think we can remove the invalidate from install_method in case
the kernel is initialized. In that case we will use >>#at:put: to
add the method that will already end in a flushCache.



Optimizations:

 MethodDictionary>>#select: will create a new MethodDictionary that
 will flush the cache when it is populated. It is wasteful and we could
 avoid this. It will only benefit VisualGST.


 Most inline caches are in-active (okay creating a VM that has both the
 jit and interpreter in one is another topic). The ideas we have talked
 about so far are:

 * OpenMP to make the invalidate spread across different cores
 * Add a global version to the IC. So the fast path would have an
   additional load, compare, branch.
 * Create a list or a flat array (and if more than 1024 entries) and
   add active entries there. So this would create additional calls
   on the hot path as well.


comments?

        holger

_______________________________________________
help-smalltalk mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/help-smalltalk

Reply via email to