我对JIT编译器的工作原理有点困惑.我知道C#编译成IL.第一次运行它是JIT'd.这是否涉及将其翻译成本机代码?.NET运行时(作为虚拟机吗?)是否与JIT代码交互?我知道这很天真,但我真的很困惑.我的印象一直是.NET运行时没有解释程序集,但我不了解交互的细节.
我试图弄清楚C#编译器如何处理尾调用.
(答案:他们不是.但是64位JIT会做TCE(尾部呼叫消除).限制适用.)
所以我使用递归调用编写了一个小测试,它打印了在StackOverflowException杀死进程之前调用它的次数.
class Program
{
static void Main(string[] args)
{
Rec();
}
static int sz = 0;
static Random r = new Random();
static void Rec()
{
sz++;
//uncomment for faster, more imprecise runs
//if (sz % 100 == 0)
{
//some code to keep this method from being inlined
var zz = r.Next();
Console.Write("{0} Random: {1}\r", sz, zz);
}
//uncommenting this stops TCE from happening
//else
//{
// Console.Write("{0}\r", sz); …Run Code Online (Sandbox Code Playgroud) 我最近一直在考虑这个问题,在我看来,JIT编译的大多数优点应该或多或少地归结为中间格式,并且jints本身并不是生成代码的好方法.
所以这些是我经常听到的主要的JIT编译参数:
它不像提前编译也没有优势.即时编译有时间限制:在程序启动时,您不能让最终用户永远等待,因此需要权衡某些事情.大多数时候他们只是减少优化.我的一个朋友有分析证据表明内联函数和"手动"展开循环(在过程中混淆源代码)对他的C#号码运算程序的性能产生了积极影响; 在我这方面做同样的事情,我的C程序填写相同的任务,没有产生任何积极的结果,我相信这是由于我的编译器允许进行广泛的转换.
然而,我们被jitted程序包围.C#和Java无处不在,Python脚本可以编译成某种字节码,我确信其他一些编程语言也是如此.我必须有一个很好的理由让我失踪.那么什么使即时编译如此优于提前编译?
编辑为了清除一些混淆,也许重要的是要声明我全都是可执行文件的中间表示.这有很多优点(实际上,实时编译的大多数参数实际上是中间表示的参数).我的问题是如何将它们编译为本机代码.
大多数运行时(或编译器)都倾向于及时或提前编译它们.由于编译器有更多的时间来执行优化,因此提前编译看起来像是一个更好的替代方案,我想知道为什么微软,Sun和所有其他人都在反过来.我对与分析相关的优化有点怀疑,因为我对即时编译程序的经验表现出很差的基本优化.
我用了一个例子与C语言代码,只是因为我需要的例子名列前茅的时间编制与刚刚在时间编译.C代码没有发送到中间表示的事实与情况无关,因为我只需要表明提前编译可以产生更好的即时结果.
在负载很重的情况下,我们的应用程序正在使一个强大的服务器达到100%的CPU使用率.读取进程转储,查看线程,其中一些是10分钟.在使用时,他们都没有给我任何见解!CLRStack.
!失控给了我:
0:030> !runaway
User Mode Time
Thread Time
53:2e804 0 days 0:10:04.703
30:31894 0 days 0:07:51.593
33:47100 0 days 0:07:24.890
42:11e54 0 days 0:06:45.875
35:35e18 0 days 0:06:07.578
41:54464 0 days 0:05:49.796
47:57700 0 days 0:05:45.000
44:3c2d4 0 days 0:05:44.265
32:3898c 0 days 0:05:43.593
50:54894 0 days 0:05:41.968
51:5bc58 0 days 0:05:40.921
43:14af4 0 days 0:05:40.734
48:35074 0 days 0:05:40.406
...
Run Code Online (Sandbox Code Playgroud)
在其中一个线程上调用!DumpStack,我得到:
0000001ab442f900 00007ff9ef4c1148 KERNELBASE!WaitForSingleObjectEx+0x94, calling ntdll!NtWaitForSingleObject
0000001ab442f980 00007ff9e920beb2 clr!SVR::gc_heap::compute_new_dynamic_data+0x17b, calling clr!SVR::gc_heap::desired_new_allocation
0000001ab442f9a0 00007ff9e90591eb clr!CLREventWaitHelper2+0x38, calling kernel32!WaitForSingleObjectEx
0000001ab442f9b0 00007ff9e90e0d2c …Run Code Online (Sandbox Code Playgroud) 当我composer --version在macOS终端中运行时,我收到以下错误:
PHP警告:preg_match():JIT编译失败:第755行的phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php中没有更多内存
Warning: preg_match(): JIT compilation failed: no more memory in phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php on line 755
PHP Warning: preg_match(): JIT compilation failed: no more memory in phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php on line 759
Warning: preg_match(): JIT compilation failed: no more memory in phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php on line 759
PHP Warning: preg_split(): JIT compilation failed: no more memory in phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php on line 654
Warning: preg_split(): JIT compilation failed: no more memory in phar:///usr/local/bin/composer.phar/vendor/symfony/console/Application.php on line 654
PHP Warning: preg_split(): JIT compilation failed: no more …Run Code Online (Sandbox Code Playgroud) 我听说过这个术语,但我不完全确定它是什么意思,所以:
我发现当我向Python提出更多要求时,python不会以100%的速度使用我的机器资源而且速度不是很快,与许多其他解释语言相比它速度很快,但与编译语言相比,我认为不同之处在于非常了不起.
使用Python 3中的Just In Time(JIT)编译器可以加快速度吗?
通常JIT编译器是唯一可以提高解释语言性能的东西,所以我指的是这个,如果其他解决方案可用,我很乐意接受新的答案.
许多动态语言实现(或想要实现)JIT编译器以加快其执行时间.不可避免地,来自花生画廊的人问他们为什么不使用LLVM.答案通常是,"LLVM不适合构建JIT." (例如,Armin Rigo的评论.)
为什么LLVM不适合构建JIT?
注意:我知道LLVM有自己的JIT.如果LLVM曾经不适合,但现在适合,请说明改变了什么.我不是在讨论在LLVM JIT上运行LLVM字节码,我在谈论使用LLVM库来实现动态语言的JIT.
令人惊讶的是,以下代码输出:
/
-1
Run Code Online (Sandbox Code Playgroud)
代码:
public class LoopOutPut {
public static void main(String[] args) {
LoopOutPut loopOutPut = new LoopOutPut();
for (int i = 0; i < 30000; i++) {
loopOutPut.test();
}
}
public void test() {
int i = 8;
while ((i -= 3) > 0) ;
String value = i + "";
if (!value.equals("-1")) {
System.out.println(value);
System.out.println(i);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了很多次以确定这种情况会发生多少次,但是不幸的是,最终还是不确定的,并且我发现-2的输出有时变成了一个周期。另外,我还尝试了删除while循环并输出-1,而没有任何问题。谁能告诉我为什么?
JDK版本信息:
public class LoopOutPut {
public static void main(String[] args) {
LoopOutPut loopOutPut = new LoopOutPut();
for (int …Run Code Online (Sandbox Code Playgroud) jit ×10
c# ×3
java ×3
.net ×2
jvm ×2
assembly ×1
benchmarking ×1
compilation ×1
composer-php ×1
llvm ×1
macos ×1
optimization ×1
performance ×1
php ×1
python ×1
python-3.x ×1
string ×1
while-loop ×1
windbg ×1
xperf ×1