all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Inefficiency in Bgotoifnil byte-code instruction
@ 2012-06-28  3:01 John Wiegley
  2012-06-28  4:38 ` Stefan Monnier
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: John Wiegley @ 2012-06-28  3:01 UTC (permalink / raw)
  To: emacs-devel

I've been doing some byte-code profiling, and have discovered that the opcodes
Bgotoifnil and Bgotoifnonnil are high up, in the top ten:

    | Bcall+3       |  1228846 | 21464419 | 21.464 |
    | Bcall+1       | 15379936 | 17113001 | 17.113 |
    | Bcall         |   895713 | 15189629 |  15.19 |
    | Bcall+6       |   105234 |  6720697 | 6.7207 |
    | Bcall+2       |  5616918 |  6043517 | 6.0435 |
    | Bgotoifnil    | 43048427 |  4416549 | 4.4165 |
    | Bvarref+6     | 63539569 |  3507246 | 3.5072 |
    | Bgotoifnonnil | 24043617 |  2474823 | 2.4748 |
    | Bgoto_char    |   517466 |  1867576 | 1.8676 |
    | Bcar          | 32846356 |  1741051 | 1.7411 |

My recommendation is that we split these into two ops: Bgotoifnil and
Bgotoifnonnil, which use only FETCH and a positive/negative offset from the
current pc, and Bgotoifnil2 and Bgotoifnonnil2 which use the old logic
(FETCH2, and an absolute offset from the start of the bytecode stream).

The resulting interpreter code would look like this:

    #ifdef BYTE_CODE_SAFE
    #define CHECK_OFFSET_RANGE(ARG)                                \
      {                                                            \
        int curpos = start.pc - stack.byte_string_start;           \
                                                                   \
        if (curpos + ARG >= bytestr_length || curpos + ARG < 0)    \
          abort ()                                                 \
      }
    #else /* not BYTE_CODE_SAFE */
    #define CHECK_OFFSET_RANGE(ARG)
    #endif /* not BYTE_CODE_SAFE */

	case Bgotoifnil:
	  {
	    Lisp_Object v1;
	    MAYBE_CG ();
	    op = FETCH;
	    v1 = POP;
	    if (NILP (v1))
	      {
		BYTE_CODE_QUIT;
		CHECK_OFFSET_RANGE (op);
		stack.pc += op;
	      }
	    break;
	  }

	case Bgotoifnil2:
	  {
	    Lisp_Object v1;
	    MAYBE_GC ();
	    op = FETCH2;
	    v1 = POP;
	    if (NILP (v1))
	      {
		BYTE_CODE_QUIT;
		CHECK_RANGE (op);
		stack.pc = stack.byte_string_start + op;
	      }
	    break;
	  }

        /* and likewise for Bgotoifnonnil... */

This way we optimize for the most used case for such a common instruction.

Making this change in the C code is easy, but changing bytecomp.el wasn't
obvious to me.  Can anyone help me with that?

John



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2012-07-10 10:31 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-28  3:01 Inefficiency in Bgotoifnil byte-code instruction John Wiegley
2012-06-28  4:38 ` Stefan Monnier
2012-06-29 16:39   ` Tom Tromey
2012-06-30  4:07     ` Stefan Monnier
2012-07-02 19:17       ` Tom Tromey
2012-07-03 13:19         ` Stefan Monnier
2012-07-03 14:45           ` Tom Tromey
2012-07-03 16:58             ` Stefan Monnier
2012-07-03 17:22               ` Tom Tromey
2012-07-03 17:53                 ` Aurélien Aptel
2012-07-03 19:24                   ` Tom Tromey
2012-07-03 23:02                 ` Stefan Monnier
2012-07-06 20:22                   ` Tom Tromey
2012-07-06 21:39                     ` Stefan Monnier
2012-07-09 19:12                   ` Tom Tromey
2012-07-10 10:31                     ` Stefan Monnier
2012-07-03 19:52             ` John Wiegley
2012-07-06 20:27           ` Tom Tromey
2012-07-02  3:51     ` John Wiegley
2012-07-02 14:08       ` Tom Tromey
2012-06-28  4:41 ` Stefan Monnier
2012-06-28 13:07 ` Richard Stallman
2012-06-28 21:24   ` John Wiegley

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.