【问题标题】:Is there a faster way to access I/O register with inp() and outp()?有没有更快的方法来使用 inp() 和 outp() 访问 I/O 寄存器?
【发布时间】:2016-03-13 21:46:18
【问题描述】:

我的应用程序在一台装有 Intel Atom Z520PT 处理器的计算机上在 DOS 下运行,该处理器的运行频率为 1.333GHz,时钟脉冲约为 0.75ns。我在 VisualStudio 2010 中使用 C 编译器。

我使用许多 inp() 和 outp() 命令来访问处理器的 I/O 寄存器。 这些命令中的每一个都需要大约 2.2µs。从 I/O 设备获取特定于应用程序的数据数组需要 40 到 50 次 outp() 和 inp() 调用,因此我每毫秒只能执行 10 次。

有什么方法可以更快地访问 I/O 寄存器吗?为什么这些命令要花这么多时间?我可以通过使用 asm 而不是 C 来加快速度吗?

【问题讨论】:

  • 您是在实际运行 DOS(如在实际的实模式 DOS 操作系统中,这在当今非常罕见)还是在 I/O 指令所在的 Windows 控制台窗口中运行 DOS 程序被虚拟化了?或者完全是别的什么?我认为 VS 2010 中的 C 编译器不会生成 DOS 可执行文件。
  • @MichaelBurr 我第二个问题! - MSVC 2010 无法创建 16 位应用程序。我的回答假设 OP 表示真正的 16 位 DOS,例如 PC-104 或类似设备上的嵌入式应用程序。

标签: c io dos intel cpu-registers


【解决方案1】:

您不太可能更快地访问这些寄存器。您没有说明设备是什么,但访问 任何 寄存器来自古老的 x86 I/O或者 ISA 总线设备会很慢。经验法则是大约 1µs 的访问时间。所以你的数字是正确的。

传统 x86 I/O 总线的 I/O 本质上很慢。 加快速度是硬件问题(不同的总线、不同的接口等),而不是软件问题。

编辑:您没有说明您正在使用的编译器, MSVC 2010 无法为 DOS 编译, 但可以假设任何可以的 16 位编译器将是类似的。例如,在Open Watcom 中,outp()inp() 无论如何都只是汇编器原语的函数包装器。函数调用开销大​​约为 1-2 个时钟,因此与 inp() 或 outp() 将花费的数千个周期相比可以忽略不计。 所以内联汇编器根本没有帮助。

根据硬件,唯一提高速度的机会是如果有其他访问方法,例如 PCI 总线主控 DMA。

【讨论】:

  • 或者如果不是 DMA,那么内存映射 I/O 可能会更快,对吧?因此,您可以在安全的地方使用写组合 movnt 存储,甚至可以使用 movnt 加载。
  • @PeterCordes 我同意,关键是它不是 I/O“端口”访问或 8 位 IO 总线 - 基本上其他任何东西都会更快。
  • 我不太了解inb / inl / outb / ... 与 MMIO 的相对性能差异,所以我不得不问。我不确定in 是否天生就比从 MMIO 读取要慢,或者什么,但我认为是这样。大多数情况下,我只是调整用户空间非特权的东西。
猜你喜欢
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
相关资源
最近更新 更多