设计一个可以直接处理 IL 的 CPU 有什么意义吗?

发布于 2024-07-12 02:45:00 字数 150 浏览 7 评论 0原文

如果我理解正确的话:

当前的CPU开发公司,如AMD和Intel,都有自己的API代码(汇编语言),他们将其视为机器代码(1G语言)之上的2G语言,这

是否可能或可取(性能)或其他)拥有一个可以在其核心执行 IL 处理而不是当前 API 调用的 CPU?

If I understand this correctly:

Current CPU developing companies like AMD and Intel have their own API codes (the assembly language) as what they see as the 2G language on top of the Machine code (1G language)

Would it be possible or desirable (performance or otherwise) to have a CPU that would perform IL handling at it's core instead of the current API calls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寄意 2024-07-19 02:45:00

Java 确实存在类似的技术 - ARM 开发了一系列可以做到这一点的 CPU,他们称之为“Jazelle”技术。

但是,.net IL 操作码表示的操作只能与堆栈上保存的类型信息结合使用,而不是单独定义。 这是与 Java 字节码的主要区别,并且会使创建合理的硬件来执行 IL 变得更加困难。

此外,IL 旨在编译为最终目标。 大多数输出​​ IL 的后端很少进行优化,而是保留语义内容,以便在最终编译步骤中进行验证和优化。 即使可以克服硬件问题,结果几乎肯定仍然比像样的优化 JIT 慢。

所以,总结一下:虽然这并非不可能,但与其他架构相比,它会非常困难,而且收效甚微。

A similar technology does exist for Java - ARM do a range of CPUs that can do this, they call it their "Jazelle" technology.

However, the operations represented by .net IL opcodes are only well-defined in combination with the type information held on the stack, not on their own. This is a major difference from Java bytecode, and would make it much more difficult to create sensible hardware to execute IL.

Moreover, IL is intended for compilation to a final target. Most back ends that spit out IL do very little optimisation, aiming instead to preserve semantic content for verification and optimisation in the final compilation step. Even if the hardware problems could be overcome, the result will almost certainly still be slower than a decent optimising JIT.

So, to sum up: while it is not impossible, it would be disproportionately hard compared to other architectures, and would achieve little.

行至春深 2024-07-19 02:45:00

你似乎对CPU的工作原理有点困惑。 汇编不是与机器代码分开的语言。 它只是它的不同(文本)表示。

汇编代码只是要执行的指令的顺序列表。 和机器码是完全一样的东西。 CPU 支持的每条指令都有一个特定的位模式来执行它,并且它还有一个可以在汇编代码中使用的文本名称。

如果我编写 add $10, $9, $8 并通过汇编器运行它,我会得到 add 指令的机器代码,获取寄存器 9 和 8 中的值,将它们相加并将结果存储在寄存器中10.

汇编程序和机器代码之间存在 1 对 1 的映射。

也没有“API 调用”。 CPU 只是从地址 X 读取,并将后续位与它理解的所有指令进行匹配。 一旦找到与该位模式匹配的指令,它就会执行该指令,然后继续读取下一条指令。

你所问的问题在某种意义上是不可能的或矛盾的。 IL 代表中间语言,即一种由编译器发出但尚未翻译成机器代码的伪代码。 但如果 CPU 可以直接执行它,那么它就不再是中间代码,而是机器代码。

因此,问题就变成了“与 CPU 现在支持的机器代码相比,您的 IL 代码是否是更好、更高效的程序表示?”

答案很可能是否定的。 MSIL(我想这就是您所说的 IL 的意思,这是一个更通用的术语)被设计为可移植、简单和一致。 每种 .NET 语言都可以编译为 MSIL,并且每个 MSIL 程序都必须能够转换为任何地方的任何 CPU 的机器代码。 这意味着 MSIL 必须是通用的、抽象的,并且不能对 CPU 做出假设。 因此,据我所知,它是一个纯粹基于堆栈的架构。 每条指令不是将数据保存在寄存器中,而是处理堆栈顶部的数据。 这是一个不错的干净且通用的系统,但它效率不高,并且不能很好地转化为 CPU 的严格结构。 (在你美妙的小型高级世界中,你可以假装堆栈可以自由增长。为了让 CPU 快速访问它,它必须存储在一些小而快速的有限大小的片上存储器中。那么会发生什么如果你的程序在堆栈上推送了太多数据?)

是的,你可以让CPU直接执行MSIL,但是你会得到什么?
您不再需要在执行前执行 JIT 代码,因此第一次启动程序时,它的启动速度会更快一些。 除此之外呢? 一旦您的 MSIL 程序经过 JIT 编译,它就会被转换为机器代码,并像最初用机器代码编写一样高效地运行。 MSIL字节码不再存在,只是CPU理解的一系列指令。

事实上,您会回到使用 .NET 之前的状态。 非托管语言直接编译为机器代码,就像您的建议一样。 唯一的区别是,非托管代码的目标是由 CPU 设计者设计的适合在 CPU 上执行的机器代码,而在您的情况下,它的目标是由软件设计者设计的易于翻译和执行的机器代码。从。

You seem a bit confused about how CPU's work. Assembly is not a separate language from machine code. It is simply a different (textual) representation of it.

Assembly code is simply a sequential listing of instructions to be executed. And machine code is exactly the same thing. Every instruction supported by the CPU has a certain bit-pattern that cause it to be executed, and it also has a textual name you can use in assembly code.

If I write add $10, $9, $8 and run it through an assembler, I get the machine code for the add instruction, taking the values in registers 9 and 8, adding them and storing the result in register 10.

There is a 1 to 1 mapping between assembler and machine code.

There also are no "API calls". The CPU simply reads from address X, and matches the subsequent bits against all the instructions it understands. Once it finds an instruction that matches this bit pattern, it executes the instruction, and moves on to read the next one.

What you're asking is in a sense impossible or a contradiction. IL stands for Intermediate Language, that is, a kind of pseudocode that is emitted by the compiler, but has not yet been translated into machine code. But if the CPU could execute that directly, then it would no longer be intermediate, it would be machine code.

So the question becomes "is your IL code a better, more efficient representation of a program, than the machine code the CPU supports now?"

And the answer is most likely no. MSIL (I assume that's what you mean by IL, which is a much more general term) is designed to be portable, simple and consistent. Every .NET language compiles to MSIL, and every MSIL program must be able to be translated into machine code for any CPU anywhere. That means MSIL must be general and abstract and not make assumptions about the CPU. For this reason, as far as I know, it is a purely stack-based architecture. Instead of keeping data in registers, each instruction processes the data on the top of the stack. That's a nice clean and generic system, but it's not very efficient, and doesn't translate well to the rigid structure of a CPU. (In your wonderful little high-level world, you can pretend that the stack can grow freely. For the CPU to get fast access to it, it must be stored in some small, fast on-chip memory with finite size. So what happens if your program push too much data on the stack?)

Yes, you could make a CPU to execute MSIL directly, but what would you gain?
You'd no longer need to JIT code before execution, so the first time you start a program, it would launch a bit faster. Apart from that, though? Once your MSIL program has been JIT'ed, it has been translated to machine code and runs as efficiently as if it had been written in machine code originally. MSIL bytecode no longer exists, just a series of instructions understood by the CPU.

In fact, you'd be back where you were before .NET. Non-managed languages are compiled straight to machine code, just like this would be in your suggestion. The only difference is that non-managed code targets machine code that is designed by CPU designers to be suitable for execution on a CPU, while in your case, it'd target machine code that's designed by software designers to be easy to translate to and from.

幻想少年梦 2024-07-19 02:45:00

这不是一个新想法 - Java 也预测了同样的事情,而且 Lisp 机器 甚至实际上是这样的实施的。

但这些经验表明它并不是真正有用 - 通过设计专用 CPU,您无法从“传统”CPU 的进步中受益,而且您很可能无法在英特尔自己的游戏中击败英特尔。 维基百科文章中的一句话很好地说明了这一点:

更便宜的台式电脑很快就能够
运行 Lisp 程序的速度甚至比
Lisp 机器,无需使用
特殊用途硬件。

从一种机器代码即时转换为另一种机器代码是一个很好理解的问题,而且很常见(现代 CISC CPU 甚至在内部做类似的事情,因为它们实际上是 RISC),我相信我们可以假设它做得足够高效避免它不会产生显着的好处 - 当它意味着您必须将自己与传统 CPU 的最新技术脱钩时就不会了。

This is not a new idea - the same thing was predicted for Java, and Lisp machines were even actually implemented.

But experience with those shows that it's not really useful - by designing special-purpose CPUs, you can't benefit from the advances of "traditional" CPUs, and you very likely can't beat Intel at their own game. A quote from the Wikipedia article illustrates this nicely:

cheaper desktop PCs soon were able to
run Lisp programs even faster than
Lisp machines, without the use of
special purpose hardware.

Translating from one kind of machine code to another on the fly is a well-understood problem and so common (modern CISC CPUs even do something like that internally because they're really RISC) that I believe we can assume it is being done efficiently enough that avoiding it does not yield significant benefits - not when it means you have to decouple yourself from the state of the art in traditional CPUs.

夜血缘 2024-07-19 02:45:00

我会说不。

计算机上需要运行的实际机器语言指令的级别低于IL。 例如,IL 并没有真正描述应如何进行方法调用、应如何管理寄存器、应如何访问堆栈或机器代码级别所需的任何其他细节。

因此,让机器直接识别 IL 可以简单地将所有 JIT 编译逻辑从软件转移到硬件中。

那会让整个过程变得非常僵化且不可改变。

通过使用基于机器功能的机器语言和基于捕获程序员意图的中间语言,您将获得更好的系统。 定义机器的人可以专注于定义高效的计算机架构,而定义 IL 系统的人可以专注于表达性和安全性等方面。

如果工具供应商和硬件供应商都必须对所有内容使用完全相同的表示,那么硬件空间或工具空间的创新都会受到阻碍。 所以,我说他们应该彼此分开。

I would say no.

The actual machine language instructions that need to run on a computer are lower level than IL. IL, for example, doesn't really describe how methods calls should be made, how registers should be managed, how the stack should be accessed, or any other of the details that are needed at the machine code level.

Getting the machine to recognize IL directly would, therefore, simple move all the JIT compilation logic from software into hardware.

That would make the whole process very rigid and unchangeable.

By having the machine language based on the capabilities of the machine, and an intermediate language based on capturing programmer intent, you get a much better system. The folks defining the machine can concentrate on defining an efficient computer architecture, and the folks defining the IL system can focus on things like expressiveness and safety.

If both the tool vendors and the hardware vendors had to use the exact same representation for everything, then innovation in either the hardware space or the tool space would be hampered. So, I say they should be separate from one another.

带上头具痛哭 2024-07-19 02:45:00

我不会这么认为,原因有两个: -

  1. 如果您有硬件处理 IL,该硬件将无法运行更新版本的 IL。 使用 JIT,您只需要一个新的 JIT,然后现有硬件就可以运行更新的 IL。
  2. IL 很简单,并且被设计为与硬件无关。 IL 必须变得更加复杂,才能以最有效的方式描述操作,从而接近现有机器代码的性能。 但这意味着 IL 很难在非 IL 特定硬件上运行。

I wouldn't have thought so for two reasons:-

  1. If you had hardware processing IL that hardware would not be able to run a newer version of IL. With JIT you just need a new JIT then existing hardware can run the newer IL.
  2. IL is simple and is designed to be hardware agnostic. The IL would have to become much more complex to enable it to describe operations in the most effecient manner in order to get anywhere close to the performance of existing machine code. But that would mean the IL would be much harder to run on non IL specific hardware.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文