TM: 6X slower with trace-abort before short inner loop, due to oscillating between interpreter and JIT

RESOLVED WORKSFORME

Status

()

defect
P2
normal
RESOLVED WORKSFORME
11 years ago
5 years ago

People

(Reporter: jruderman, Unassigned)

Tracking

(Blocks 1 bug, {perf, testcase})

Trunk
x86
macOS
Points:
---
Dependency tree / graph
Bug Flags:
blocking1.9.1 -
wanted1.9.1 +

Firefox Tracking Flags

(Not tracked)

Details

Reporter

Description

11 years ago
for (var i = 0; i < 500000; ++i) {
  ~{};
  for (var j = 0; j < 4; ++j) {
  }
}

3X slower with JIT enabled

for (var i = 0; i < 500000; ++i) {
  true % 3;
  for (var j = 0; j < 4; ++j) {
  }
}

6X slower with JIT enabled

The weird thing is that if I remove the inner loop, I get an abort during recording, so it's only 10-30% slower.  But with the inner loop present, it traces and then keeps hitting a side exit(?), making it several times slower.  Aborting is probably reasonable for these testcases; why does the inner loop prevent it from aborting?
The side exit is expected, because it doesn't take long for j to hit 4.  I suspect the overhead of entering and exiting the trace for the inner loop every time is the problem here, but I have not tested this theory.

Do we have any heuristics to blacklist and trash trace trees that consistently execute for only a short time before side exiting?
Reporter

Comment 2

11 years ago
Oh, I get it.  It *does* abort recording of the outer loop, but still records the inner loop, forcing repeated jumps between the interpreter and the JIT.  Nasty.
Reporter

Updated

11 years ago
Summary: TM: 6X slower with unhappy operator before inner loop (fails to abort recording?) → TM: 6X slower with trace-abort before short inner loop, due to oscillating between interpreter and JIT

Comment 3

11 years ago
The problem here is that we create an inner loop, but we don't capture the outer loop around it due to the ~{}; and true % 3 (which makes us abort). The inner loop is a net perf loss because it doesn't do anything except unpack/repack its stack. The outer loop could embed the inner loop if we trace that path. I think the goal is here to not abort for any sensible cose. How sensible is ~{} though?
Reporter

Updated

11 years ago
Duplicate of this bug: 470738
Reporter

Comment 5

11 years ago
> I think the goal is here to not abort for any sensible code. 
> How sensible is ~{} though?

Not very.  But I believe DOM calls aren't going to be traced for Firefox 3.1, so I worry that this issue will slow down scripts whose only "mistake" is to mix DOM manipulation with light computation.
Flags: blocking1.9.1?

Comment 6

11 years ago
not blocking on ~{}
Flags: wanted1.9.1+
Flags: blocking1.9.1?
Flags: blocking1.9.1-

Comment 7

11 years ago
If the thing causing the abort were a DOM call, this would be nothing too serious, since "~{}" is going to be real fast in comparison.

Of course, if you can make this a real case in a web page, let's reconsider.

Updated

11 years ago
Priority: -- → P2

Comment 8

10 years ago
Bug 535925 has a type-unstable outer loop (which is blacklisted) and a short, traced inner loop. Performance is 15.3s with JIT, 8.7s without. It's reduced from a real-world example.

Comment 9

10 years ago
For me the second example from comment 1 seems to trace now. The first example doesn't (500,000 exits) and using an optimised build on windows is about 50% slower with JIT.
Still a problem in the JM+TI world?
Run the tests and see?
With a current shell:
Testcase 1
js -b 470779-1.js
runtime = 775.066 ms
js -b -m -n 470779-1.js
runtime = 381.890 ms

Testcase 2
js -b 470779-2.js
runtime = 324.557 ms
js -b -m -n 470779-2.js
runtime = 11.616 ms

Looks better to me!
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.