Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux x86 GAS assembly中,是否可以在没有系统调用的情况下创建线程?_Linux_Multithreading_Assembly_Gnu Assembler - Fatal编程技术网

在Linux x86 GAS assembly中,是否可以在没有系统调用的情况下创建线程?

在Linux x86 GAS assembly中,是否可以在没有系统调用的情况下创建线程?,linux,multithreading,assembly,gnu-assembler,Linux,Multithreading,Assembly,Gnu Assembler,在学习“汇编语言”(在x86体系结构上的linux中使用GNU作为汇编程序)的同时,aha的一个重要时刻是使用的可能性。这些系统调用非常方便,有时甚至是作为程序所必需的。 然而,系统调用在性能方面相当昂贵,因为它们需要中断(当然还有系统调用),这意味着必须从用户空间中当前的活动程序切换到内核空间中运行的系统 我想说的一点是:我目前正在实现一个编译器(用于一个大学项目),我想添加的额外功能之一是支持多线程代码,以提高编译程序的性能。因为一些多线程代码将由编译器本身自动生成,这几乎可以保证其中也会有

在学习“汇编语言”(在x86体系结构上的linux中使用GNU作为汇编程序)的同时,aha的一个重要时刻是使用的可能性。这些系统调用非常方便,有时甚至是作为程序所必需的。
然而,系统调用在性能方面相当昂贵,因为它们需要中断(当然还有系统调用),这意味着必须从用户空间中当前的活动程序切换到内核空间中运行的系统

我想说的一点是:我目前正在实现一个编译器(用于一个大学项目),我想添加的额外功能之一是支持多线程代码,以提高编译程序的性能。因为一些多线程代码将由编译器本身自动生成,这几乎可以保证其中也会有非常少量的多线程代码。为了获得性能上的胜利,我必须确保使用线程能够实现这一点

然而,我担心的是,为了使用线程,我必须进行系统调用和必要的中断。因此,微小的(自动生成的)线程将受到执行这些系统调用所需时间的高度影响,这甚至可能导致性能损失

因此,我的问题有两个方面(下面还有一个额外的问题):

  • 可以编写汇编程序吗 可以运行多个线程的代码 同时在多个核上 一次,不需要系统 电话
  • 如果我有非常小的线程(与线程的总执行时间一样小)、性能损失,或者根本不值得付出努力,那么我会获得性能提升吗

我的猜测是,如果没有系统调用,多线程汇编代码是不可能的。即使是这样,您是否有尽可能高效地实现线程的建议(或更好的建议:一些真正的代码?

实现用户模式线程

历史上,线程模型被概括为N:M,也就是说,在M个内核模型线程上运行N个用户模式线程。现代的使用率是1:1,但并不总是这样,也不一定要这样


您可以在单个内核线程中自由维护任意数量的用户模式线程。只是你有责任经常在它们之间切换,让它们看起来是并行的。你的线程当然是合作的,而不是先发制人的;基本上,您在自己的代码中分散了yield()调用,以确保定期切换。

首先,您应该学习如何使用C语言中的线程(pthreads、POSIX thead)。在GNU/Linux上,您可能希望使用POSIX线程或GLib线程。 然后您可以简单地从汇编代码中调用C

以下是一些要点:

  • Posix线程:
  • 您将学习如何从汇编调用C函数的教程:
  • Butenhof关于POSIX线程的书

系统调用现在并没有那么慢,用
syscall
sysenter
代替
int
。尽管如此,当您创建或销毁线程时,只会产生开销。一旦它们运行,就不会有系统调用。用户模式线程不会真正帮助您,因为它们只在一个内核上运行。

如果您想获得性能,您必须利用内核线程。只有内核可以帮助您在多个CPU内核上同时运行代码。除非您的程序是I/O绑定的(或执行其他阻塞操作),否则执行用户模式协作多线程(也称为)不会获得任何性能。您只需执行额外的上下文切换,但实际线程运行的一个CPU仍将以100%的速度运行

系统调用速度加快了。现代CPU支持
sysenter
指令,这比旧的
int
指令快得多。另请参阅,了解Linux如何以最快的方式进行系统调用


确保自动生成的多线程使线程运行足够长的时间,以获得性能。不要试图并行化短小的代码,这只会浪费时间生成和加入线程。还要警惕内存影响(尽管这些影响很难测量和预测)——如果多个线程访问独立的数据集,它们的运行速度将比由于问题而重复访问同一数据时快得多。

简单的回答是,您不能。当您编写汇编代码时,它在一个且仅在一个逻辑(即硬件)线程上按顺序(或通过分支)运行。如果希望某些代码在另一个逻辑线程上执行(无论是在同一个内核上,还是在同一个CPU上的不同内核上,甚至是在不同的CPU上),则需要让操作系统设置另一个线程的指令指针(
CS:EIP
)以指向要运行的代码。这意味着使用系统调用让操作系统执行您想要的操作

用户线程不会提供您想要的线程支持,因为它们都在同一硬件线程上运行

编辑:将Ira Baxter的答案与Parlanse合并。如果您确保您的程序在每个逻辑线程中运行一个线程,那么您可以构建自己的调度程序,而无需依赖操作系统。无论哪种方式,您都需要一个调度程序来处理从一个线程跳到另一个线程的过程。在调用调度程序之间,没有处理多线程的特殊汇编指令。调度程序本身不能依赖于任何特殊的程序集,而是依赖于每个线程中调度程序部分之间的约定

无论是哪种方式,无论您是否使用操作系统,您仍然必须依赖于某些调度程序来处理跨线程执行。

“是否这样做?”