Assembly IO请求排队

Assembly IO请求排队,assembly,io,operating-system,Assembly,Io,Operating System,这是关于等待IO的调用,允许上下文切换,或非阻塞调用模型: 它们究竟是如何在操作系统中实现的 底层设备如何在指令级别上工作?例如,存储和网络硬件的确切CPU指令 一个设备一次可以挂起多少IO指令 在操作系统(例如Linux和Windows)中,一次可以排队处理多少IO请求?在何处查找其他操作系统的此信息 编辑:这是一个既广泛又具体的问题。这是关于IO设备和CPU的,操作系统使用它来完成任务-所以请回答你能回答的问题。这也是关于内存的,因为每个IO操作都涉及数据的内存(如果不是寻址的话)。x86和

这是关于等待IO的调用,允许上下文切换,或非阻塞调用模型:

  • 它们究竟是如何在操作系统中实现的
  • 底层设备如何在指令级别上工作?例如,存储和网络硬件的确切CPU指令
  • 一个设备一次可以挂起多少IO指令
  • 在操作系统(例如Linux和Windows)中,一次可以排队处理多少IO请求?在何处查找其他操作系统的此信息
  • 编辑:这是一个既广泛又具体的问题。这是关于IO设备和CPU的,操作系统使用它来完成任务-所以请回答你能回答的问题。这也是关于内存的,因为每个IO操作都涉及数据的内存(如果不是寻址的话)。x86和/或广泛分类的答案就可以了。对于设备,您可以选择x86上的网络/存储

  • 一般来说,阻塞I/O调用可以做到这一点:1)将进程/线程放在等待I/O完成的进程/线程列表上,2)将其标记为不可运行,3)调用上下文开关。由于发出阻塞调用的线程现在被标记为不可运行,因此操作系统的调度程序将永远不会计划它在CPU上运行,直到I/O操作完成,并且该线程再次被标记为可运行。这就是“阻塞”的实际含义

    Linux有一个用于非阻塞I/O调用的接口,其工作原理大致如下:您的程序首先进行系统调用以创建“异步I/O上下文”。这是一个对象,其中包含一个队列,用于在I/O操作完成时生成的通知事件。内核传回一个AIO上下文标识符,您的程序在进行后续调用时使用该标识符。然后,当您想要执行一些I/O时,您可以进行另一个系统调用来“提交”异步I/O操作以供执行。您可以提交任意数量的内容。完成后,通知将累积在AIO上下文的事件队列中。稍后,只要您愿意,就可以进行另一个系统调用以从该队列检索通知

    (有趣的是,尽管Linux支持这些系统调用已有一段时间了,但Glibc仍然没有使用它们!Glibc通过内部生成工作线程并在工作线程中执行阻塞I/O操作来实现非阻塞I/O!)

  • 基本上有3例。在x86上,有
    IN
    OUT
    指令用于向硬件设备传输1/2/4字节或从硬件设备传输1/2/4字节。x86有一个特殊的16位地址空间,用于这些指令访问的“I/O端口”。(我不知道其他架构是否也有特殊的I/O地址空间。)即使在x86上,也不是所有硬件设备都映射到该I/O地址空间。有些使用常规内存地址空间。在这种情况下,您可以使用普通
    MOV
    指令或任何其他访问内存的指令向它们传输数据。第三种情况是使用DMA(直接内存访问)时。基本上,您可以使用前面提到的两种方法之一向硬件设备发送某种命令,告诉它:“从地址Y开始,将X字节直接传输到RAM”。然后,设备直接通过系统总线发送请求的数据,并将其存储在RAM中,而无需CPU的任何干预。当它完成时,通常会发出一个中断来让您知道

  • 这完全取决于设备。没有一般性的答案

  • 好吧,这是我能给你的最接近答案的东西,对于Linux。在Linux中,每个存储设备都有自己的未完成I/O请求队列。这些队列中的每个队列都有一个名为
    nr_requests
    的变量,该变量是它将持有的未完成I/O请求的最大数量。通过打印出以下伪文件,您可以找到硬盘驱动器的值:
    /sys/block//queue/nr\u requests
    。默认值似乎是128。从读取源代码来看,128似乎也是最大值(?)

  • 后记:如果您正在考虑编写一些超高性能的I/O服务器应用程序,或者其他什么,请在您感兴趣的所有OSs和硬件平台上进行基准测试!您可以编写两个简单的测试程序,生成一组线程(使数量可配置),并以每秒(可配置)的速率启动(可配置)数量的I/O操作。观察它们完成所需的时间、测试运行时服务器的响应方式以及出错的操作数。

    1。它们究竟是如何在操作系统中实现的? 提出请求

    让我们看看在设备上调用写操作时会发生什么

  • 您要求运行时执行文件写入
  • 最后运行时调用一个系统调用
  • 内核将定位与您写入的设备关联的驱动程序/模块
  • 驱动程序/模块执行其操作,并可将请求转发给其他驱动程序/模块
  • 最后一个驱动程序/模块专门处理硬件设备、记录请求并发送写入命令
  • 将任务置于睡眠状态 最后一个驱动程序/模块返回一个状态代码,以便通知其调用者发生了什么。为简单起见,假设返回状态仅为:成功、失败、挂起。
    通过返回挂起,驱动程序/模块通知请求正在进行。
    控件从5返回。到2。其中内核被赋予写入的返回状态。
    如果是成功或错误,则返回用户空间,指示成功或失败。但是,如果它处于挂起状态,它会将程序标记为等待IO(通过使用任何操作系统特定的方法)。
    这是关键点,一个正在等待的任务没有计划,即使它没有其他事情可做。
    从1开始。到五点。内核可以(在大多数操作系统中,并且只有当