v8 引擎 - 为什么从 JS 调用本机代码如此昂贵? [英] v8 Engine - Why is calling native code from JS so expensive?

查看:24
本文介绍了v8 引擎 - 为什么从 JS 调用本机代码如此昂贵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于对其他问题的多个答案,从 Javascript 调用本机 C++ 的成本很高.

我用节点模块基准"检查了自己,得出了相同的结论.

一个简单的 JS 函数可以直接获得约 90 000 000 次调用,当调用 C++ 函数时,我最多可以获得大约 25 000 000 次调用.这本身并没有那么糟糕.

但是当添加一个对象的创建时,JS 仍然是大约 70 000 000 次调用/秒,但是原生版本受到了巨大的影响,下降到大约 2 000 000 次.

我认为这与 v8 引擎如何工作的动态特性有关,并且它将 JS 代码编译为字节码.

但是是什么阻止他们对 C++ 代码实现相同的优化?(或至少打电话/深入了解有什么帮助)

解决方案

(此处为 V8 开发人员.)没有看到您运行的代码,很难完全确定您观察到的效果,根据您的描述,我可以不要复制它.尤其是微基准测试往往很棘手,而且它们似乎衡量的相对加速或减速通常具有误导性,除非您已经确认幕后发生的事情正是您期望发生的事情.例如,可能是优化编译器能够消除整个工作负载,因为它可以静态证明结果没有在任何地方使用.或者可能根本没有调用发生,因为编译器选择内联被调用者.

一般来说,跨越 JS/C++ 边界是有一定成本的,因为不同的调用约定和一些其他需要做的检查和准备,比如检查可能抛出的异常.一个 JavaScript 函数调用另一个函数,一个 C++ 函数调用另一个函数,将比 JavaScript 调用 C++ 或相反的方式更快.<​​/p>

这种跨界成本与任何一方的编译器优化级别无关.它也与字节码无关.(热",即频繁执行,JavaScript 函数无论如何都会编译为机器代码.)

最后,V8 不是 C++ 编译器.它根本不是为了对 C++ 代码进行任何优化而构建的.即使它尝试这样做,也没有理由认为它可以比您现有的带有 -O3 的 C++ 编译器做得更好.(V8 甚至看不到 C++ 模块的源代码,因此在尝试重新编译它之前,您必须弄清楚如何提供该源代码.)

Based on multiple answers to other questions, calling native C++ from Javascript is expensive.

I checked myself with the node module "benchmark" and came to the same conclusion.

A simple JS function can get ~90 000 000 calls directly, when calling a C++ function I can get a maximum of about 25 000 000 calls. That in itself is not that bad.

But when adding the creation of an object the JS still is about 70 000 000 calls/sec, but the native version suffers dramatically and goes down to about 2 000 000.

I assume this has todo with the dynamic nature of how the v8 engine works, and that it compiles the JS code to byte code.

But what keeps them from implementing the same optimizations for the C++ code? (or at least calling / insight into what would help there)

解决方案

(V8 developer here.) Without seeing the code that you ran, it's hard to be entirely sure what effect you were observing, and based on your descriptions I can't reproduce it. Microbenchmarks in particular tend to be tricky, and the relative speedups or slowdowns they appear to be measuring are often misleading, unless you've verified that what happens under the hood is exactly what you expect to be happening. For example, it could be the case that the optimizing compiler was able to eliminate the entire workload because it could statically prove that the result isn't used anywhere. Or it could be the case that no calls were happening at all, because the compiler chose to inline the callee.

Generally speaking, crossing the JS/C++ boundary is what has a certain cost, due to different calling conventions and some other checks and preparations that need to be done, like checking for exceptions that may have been thrown. Both one JavaScript function calling another, and one C++ function calling another, will be faster than JavaScript calling into C++ or the other way round.

This boundary crossing cost is unrelated to the level of compiler optimization on either side. It's also unrelated to byte code. ("Hot", i.e. frequently executed, JavaScript functions are compiled to machine code anyway.)

Lastly, V8 is not a C++ compiler. It's simply not built to do any optimizations for C++ code. And even if it tried to, there's no reason to assume it could do a better job than your existing C++ compiler with -O3. (V8 also doesn't even see the source code of your C++ module, so before you could experiment with recompiling that, you'd have to figure out how to provide that source.)

这篇关于v8 引擎 - 为什么从 JS 调用本机代码如此昂贵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆