JS Math JITing - JSConf.eu

  • 6,856 views
Uploaded on

 

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
6,856
On Slideshare
0
From Embeds
0
Number of Embeds
7

Actions

Shares
Downloads
38
Comments
0
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. Untyped Compilationfunction f(left, right) { var t = left + right ...}
  • 2. Untyped Compilation Compile Everything!function f(left, right) { var t = left + right ...}
  • 3. Untyped Compilation Compile Everything! ... but only one type at a time.function f(left, right) { var t = left + right ...}
  • 4. Let’s Compile Numbers JavaScript numbers are floatsfunction f(left, right) { var t = left + right ...}f(5, 10);
  • 5. Let’s Compile Numbers JavaScript numbers are floats ... but we can use integers, toofunction f(left, right) { var t = left + right ...}f(5, 10);
  • 6. Integer Add Register Variable edi left.type eax left.data ebx right.type edx right.data
  • 7. Integer Add Register Variable edi left.type eax left.dataadd edx, eax ebx right.type edx right.data
  • 8. Register Variable Value edi left.type STRING eax left.data “a”add edx, eax ebx right.type INT32 edx right.data 35
  • 9. Oh no, a string Register Variable Value edi left.type STRING eax left.data “a”add edx, eax ebx right.type INT32 edx right.data 35
  • 10. Oh no, a string Register Variable Value edi left.type STRING Integer add is bogus! eax left.data “a”add edx, eax ebx right.type INT32 edx right.data 35
  • 11. Integers, Untyped JIT Register Variable edi left.typecmp edi, 0xffffff81jne other eax left.datacmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type edx right.data
  • 12. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 13. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 14. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 15. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 16. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 17. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 18. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 19. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 20. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 21. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 22. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 23. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 35
  • 24. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 27cmp ebx, 0xffffff81jne otheradd edx, eax ebx t.type right.type INT32 edx t.data right.data 62 35
  • 25. What about... Calling f() with a huge integer?function f(left, right) { var t = left + right ...}f(2147483647, 2147483647);
  • 26. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 2^31-1
  • 27. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32 edx right.data 2^31-1
  • 28. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eax ebx t.type right.type INT32 edx t.data right.data -2 2^31-1
  • 29. JavaScript Numbersjs> 2147483647 + 2147483647
  • 30. JavaScript Numbersjs> 2147483647 + 2147483647 ↵4294967294
  • 31. JavaScript Numbersjs> 2147483647 + 21474836474294967294js> 4294967294 == -2
  • 32. JavaScript Numbersjs> 2147483647 + 21474836474294967294js> 4294967294 == -2 ↵false
  • 33. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eax ebx right.type INT32jo stub edx right.data 2^31-1
  • 34. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eaxjo stub ebx t.type right.type INT32 edx t.data right.data -2 2^31-1
  • 35. Integers, Untyped JIT Register Variable Value edi left.type INT32cmp edi, 0xffffff81jne other eax left.data 2^31-1cmp ebx, 0xffffff81jne otheradd edx, eaxjo stub ebx t.type right.type INT32 edx t.data right.data -2 2^31-1
  • 36. Hey! What about floats?function f(left, right) { var t = left + right ...}f(2.717, Math.PI);
  • 37. Floats, Untyped JITcmp edi, 0xffffff81jne othercmp ebx, 0xffffff81jne otheradd edx, eaxjo stub
  • 38. Floats, Untyped JIT cmp edi, 0xffffff80 jae stub cmp edi, 0xffffff80 jb skip_convert cmp ebx, 0xffffff81 jne stubcmp edi, 0xffffff81 cvtsi2sd xmm5, eaxjne other jmp convertedcmp ebx, 0xffffff81 skip_convert: movd xmm5, eaxjne other pinsrd xmm5, ebx, 1add edx, eax converted:jo stub movd xmm6, edx pinsrd xmm6, edi, 1 jmp add
  • 39. Floats, Untyped JIT cmp edi, 0xffffff80 jae stub cmp edi, 0xffffff80 jb skip_convert cmp ebx, 0xffffff81 jne stubcmp edi, 0xffffff81 cvtsi2sd xmm5, eaxjne other jmp convertedcmp ebx, 0xffffff81 skip_convert: movd xmm5, eaxjne other pinsrd xmm5, ebx, 1add edx, eax converted:jo stub movd xmm6, edx pinsrd xmm6, edi, 1 jmp add cmp ebx, 0xffffff80 jae stub cvtsi2sd xmm6, ecx movd xmm5, eax pinsrd xmm5, ebx, 1 jmp add
  • 40. Floats, Untyped JIT cmp edi, 0xffffff80 jae stub cmp edi, 0xffffff80 jb skip_convert cmp ebx, 0xffffff81 jne stubcmp edi, 0xffffff81 cvtsi2sd xmm5, eaxjne other jmp convertedcmp ebx, 0xffffff81 skip_convert: movd xmm5, eaxjne other pinsrd xmm5, ebx, 1add edx, eax converted:jo stub movd xmm6, edx pinsrd xmm6, edi, 1 jmp add cmp ebx, 0xffffff80 jae stub cvtsi2sd xmm6, ecx movd xmm5, eax add: pinsrd xmm5, ebx, 1 addsd xmm6, xmm5 jmp add movsd [ebp+0x50], xmm6 movl edx, [ebp+0x50] jmp rejoin
  • 41. Floats, Untyped JIT cmp edi, 0xffffff80 jae stub cmp edi, 0xffffff80 jb skip_convert cmp ebx, 0xffffff81 jne stubcmp edi, 0xffffff81 cvtsi2sd xmm5, eaxjne other jmp convertedcmp ebx, 0xffffff81 skip_convert: movd xmm5, eaxjne other pinsrd xmm5, ebx, 1add edx, eax converted:jo stub movd xmm6, edx pinsrd xmm6, edi, 1 jmp add cmp ebx, 0xffffff80 jae stub cvtsi2sd xmm6, ecx movd xmm5, eax add: pinsrd xmm5, ebx, 1 addsd xmm6, xmm5 jmp add movsd [ebp+0x50], xmm6 movl edx, [ebp+0x50] jmp rejoin 30 instructions!
  • 42. Benchmark...
  • 43. Benchmark...function distance(a, b) { var t; for (var i = 0; i < a; i++) { for (var j = 0; j < b; j++) { t = ((a - i) * (a - i)) + ((b - j) * (b - j)); } }}
  • 44. The Whole Loop cmp    $0xffffff81,%ebx jne    0xf73ef58f (b - j)cmp    $0xffffff81,%edi cmp    $0xffffff81,%edxjne    0xf73ef353 (a - i) jne    0xf73ef5cccmp    $0xffffff81,%esi cmp    $0xffffff81,%edx sub    %esi,%eax cmp    $0xffffff81,%edxjne    0xf73ef390 jne    0xf73ef4ce jo     0xf73ef5f4 jne    0xf73ef72b cmp    $0xffffff81,%edisub    %edx,%ecx cmp    $0xffffff81,%ebx cmp    $0xffffff81,%ebx jne    0xf73ef7f5jo     0xf73ef3b8 * jne    0xf73ef50b imul   %eax,%ecx jo     0xf73ef550 * jne    0xf73ef768 imul   %edi,%eax jo     0xf73ef7b0 + cmp    $0xffffff81,%ebx jne    0xf73ef832 add    %eax,%edxcmp    $0xffffff81,%edi test   %ecx,%ecx cmp    $0xffffff81,%ebx test   %eax,%eax jo     0xf73ef85ajne    0xf73ef40c je     0xf73ef533 jne    0xf73ef65a je     0xf73ef790 (a - i)cmp    $0xffffff81,%esijne    0xf73ef449sub    %edx,%eax (b - j) cmp    $0xffffff81,%edx jne    0xf73ef697 sub    %esi,%edijo     0xf73ef471 jo     0xf73ef6bf
  • 45. The Whole Loop ~230 instructions cmp    $0xffffff81,%ebx jne    0xf73ef58f (b - j)cmp    $0xffffff81,%edi cmp    $0xffffff81,%edxjne    0xf73ef353 (a - i) jne    0xf73ef5cccmp    $0xffffff81,%esi cmp    $0xffffff81,%edx sub    %esi,%eax cmp    $0xffffff81,%edxjne    0xf73ef390 jne    0xf73ef4ce jo     0xf73ef5f4 jne    0xf73ef72b cmp    $0xffffff81,%edisub    %edx,%ecx cmp    $0xffffff81,%ebx cmp    $0xffffff81,%ebx jne    0xf73ef7f5jo     0xf73ef3b8 * jne    0xf73ef50b imul   %eax,%ecx jo     0xf73ef550 * jne    0xf73ef768 imul   %edi,%eax jo     0xf73ef7b0 + cmp    $0xffffff81,%ebx jne    0xf73ef832 add    %eax,%edxcmp    $0xffffff81,%edi test   %ecx,%ecx cmp    $0xffffff81,%ebx test   %eax,%eax jo     0xf73ef85ajne    0xf73ef40c je     0xf73ef533 jne    0xf73ef65a je     0xf73ef790 (a - i)cmp    $0xffffff81,%esijne    0xf73ef449sub    %edx,%eax (b - j) cmp    $0xffffff81,%edx jne    0xf73ef697 sub    %esi,%edijo     0xf73ef471 jo     0xf73ef6bf
  • 46. The Whole Loop ~230 instructions cmp    $0xffffff81,%ebx jne    0xf73ef58f (b - j)cmp    $0xffffff81,%edi cmp    $0xffffff81,%edxjne    0xf73ef353 (a - i) jne    0xf73ef5cccmp    $0xffffff81,%esi cmp    $0xffffff81,%edx sub    %esi,%eax cmp    $0xffffff81,%edxjne    0xf73ef390 jne    0xf73ef4ce jo     0xf73ef5f4 jne    0xf73ef72b cmp    $0xffffff81,%edisub    %edx,%ecx cmp    $0xffffff81,%ebx cmp    $0xffffff81,%ebx jne    0xf73ef7f5jo     0xf73ef3b8 * jne    0xf73ef50b imul   %eax,%ecx jo     0xf73ef550 * jne    0xf73ef768 imul   %edi,%eax jo     0xf73ef7b0 + cmp    $0xffffff81,%ebx jne    0xf73ef832 add    %eax,%edxcmp    $0xffffff81,%edi test   %ecx,%ecx cmp    $0xffffff81,%ebx test   %eax,%eax jo     0xf73ef85ajne    0xf73ef40c je     0xf73ef533 jne    0xf73ef65a je     0xf73ef790 (a - i)cmp    $0xffffff81,%esijne    0xf73ef449sub    %edx,%eax (b - j) cmp    $0xffffff81,%edx jne    0xf73ef697 sub    %esi,%edijo     0xf73ef471 jo     0xf73ef6bf JägerMonkey runs 100mil iterations in 1012ms
  • 47. Can we do better?function distance(a, b) { var t; for (var i = 0; i < a; i++) { for (var j = 0; j < b; j++) { t = ((a - i) * (a - i)) + ((b - j) * (b - j)); } }}
  • 48. Typed Optimizationsfunction distance(a, b) { var t; for (var i = 0; i < a; i++) { for (var j = 0; j < b; j++) { t = ((a - i) * (a - i)) + ((b - j) * (b - j)); } }}
  • 49. Hoisting Move computation outside of the loopfunction distance(a, b) { var t; for (var i = 0; i < a; i++) { var t0 = ((a - i) * (a - i)); for (var j = 0; j < b; j++) { t = t0 + ((b - j) * (b - j)); } }}
  • 50. Why only Typed JITs?var ham = 0;var obj = { valueOf: function () { return ham++; } }f(obj, obj);
  • 51. Why only Typed JITs? “ham” must be incrementedvar ham = 0;var obj = { valueOf: function () { return ham++; } }f(obj, obj);
  • 52. Typed Optimizationfunction distance(a, b) { var t; for (var i = 0; i < a; i++) { var t0 = ((a - i) * (a - i)); for (var j = 0; j < b; j++) { t = t0 + ((b - j) * (b - j)); } }}
  • 53. Elimination Redundant (b - j)function distance(a, b) { eliminated var t; for (var i = 0; i < a; i++) { var t0 = ((a - i) * (a - i)); for (var j = 0; j < b; j++) { var temp = (b - j); t = t0 + (temp * temp); } }}
  • 54. Typed JIT - IonMonkey sub    eax, ecx       ; t0 = (b - j) jo     0xf73ed01d imul   eax, eax       ; t1 = (t0 * t0) jo     0xf73ed022 test   eax, eax je     0xf73ed022 add    ebx, eax       ; t2 = (expr) + t1 jo     0xf73ed027
  • 55. Typed JIT - IonMonkey sub    eax, ecx       ; t0 = (b - j) jo     0xf73ed01d imul   eax, eax       ; t1 = (t0 * t0) jo     0xf73ed022 test   eax, eax je     0xf73ed022 add    ebx, eax       ; t2 = (expr) + t1 jo     0xf73ed027 Runs in 250ms, or 3.8X faster!
  • 56. Smartersub    eax, ecx       ; t0 = (b - j)jo     0xf73ed01dimul   eax, eax       ; t1 = (t0 * t0)jo     0xf73ed022add    ebx, eax       ; t2 = (expr) + t1jo     0xf73ed027 Runs in 220ms, or 4.6X faster!
  • 57. Arithmetic in Cmovl ecx, ebxsubl ecx, ebximul ecx, ecxaddl ecx, esi
  • 58. Arithmetic in Cmovl ecx, ebx •C: 97mssubl ecx, ebx •Untyped JIT within 10Ximul ecx, ecx •Typed JIT within ~2Xaddl ecx, esi
  • 59. Semantic Gap• No way to tell JS, “use integers”• C distinguishes float/ints