Hi all, I've been playing around a little bit with "perf" and Valgrind's cachegrind tool, and I noticed that the number of branch prediction misses can be reduced if the argvector reusing check can be hardcoded for cases where we know the size of the calling function's argvector.
Here's a simple patch to make this happen (works on both the master and chicken-5 branches). I also noticed that for some benchmarks, the number of branches went up, and missed branches too, compared to current master. I'm not sure what to make of that. Perhaps this is due to inlining differences. Cheers, Peter
From 1e6685d0fb9580a34a407ef8fa62f42eb1266268 Mon Sep 17 00:00:00 2001 From: Peter Bex <pe...@more-magic.net> Date: Thu, 15 Dec 2016 23:44:35 +0100 Subject: [PATCH] Statically determine if av can be reused or not. This is faster due to avoiding branch prediction misses. --- c-backend.scm | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/c-backend.scm b/c-backend.scm index 2479986..02b3393 100644 --- a/c-backend.scm +++ b/c-backend.scm @@ -477,19 +477,27 @@ (let* ((n (length args)) (avl (+ n (if selfarg 1 0))) (caller-has-av? (not (or (lambda-literal-customizable ll) - (lambda-literal-direct ll))))) + (lambda-literal-direct ll)))) + (caller-argcount (lambda-literal-argument-count ll)) + (caller-rest-mode (lambda-literal-rest-argument-mode ll))) ;; Try to re-use argvector from current function if it is ;; large enough. push-args gets used only for functions in ;; CPS context, so callee never returns to current function. ;; And even so, av[] is already copied into temporaries. - (cond (caller-has-av? - (gen #t "C_word *av2;") - (gen #t "if(c >= " avl ") {") - (gen #t " av2=av; /* Re-use our own argvector */") - (gen #t "} else {") - (gen #t " av2=C_alloc(" avl ");") - (gen #t "}")) - (else (gen #t "C_word av2[" avl "];"))) + (cond + ((or (not caller-has-av?) ; Argvec missing or + (and (< caller-argcount avl) ; known to be too small? + (eq? caller-rest-mode 'none))) + (gen #t "C_word av2[" avl "];")) + ((>= caller-argcount avl) ; Argvec known to be re-usable? + (gen #t "C_word *av2=av; /* Re-use our own argvector */")) + (else ; Need to determine dynamically. This is slower. + (gen #t "C_word *av2;") + (gen #t "if(c >= " avl ") {") + (gen #t " av2=av; /* Re-use our own argvector */") + (gen #t "} else {") + (gen #t " av2=C_alloc(" avl ");") + (gen #t "}"))) (when selfarg (gen #t "av2[0]=" selfarg ";")) (do ((j (if selfarg 1 0) (add1 j)) (args args (cdr args))) -- 2.1.4
signature.asc
Description: Digital signature
_______________________________________________ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers