我的程序和硬件之间有多少层?

时间:2010-04-14 21:09:54

标签: performance hardware abstraction

我不知何故感觉现代系统,包括运行时库,这个异常处理程序和内置调试器在我的(C ++)程序和CPU /其余硬件之间构建了越来越多的层。

我在考虑这样的事情:

1 + 2>> OS顶层>>运行时库/帮助程序/错误处理程序>>很多DLL模块>> OS内核层>>你真的想要运行1 + 2吗?-Windows popup(不要认真对待)>> OS内核层>>硬件抽象>>硬件>>通过至少100英里的电路>>最终到达CPU>> ADD 1,2>>一直回到我的程序

几乎所有的技术问题都是错误的,并且是以一些随机的顺序,但你明白我的观点是正确的吗?

  • 运行在Windows上运行时计算1 + 2的C ++程序时,此链的长度/更短是多长/短?

  • 当我在翻译中这样做时怎么样? (Python的|红宝石| PHP)

  • 这条连锁在现实中真的如此戏剧性吗? Windows真的试着“不要阻挡”吗?例如:直接连接我的二进制<>硬件

3 个答案:

答案 0 :(得分:3)

C ++中的“1 + 2”直接转换为直接在CPU上执行的add汇编指令。您引用的所有“层”实际上只在您开始调用库函数时才起作用。例如,简单的printf("Hello World\n");将经历多个层(使用Windows作为示例,不同的操作系统会有所不同):

  1. CRT - C运行时实现%d替换之类的东西并创建一个字符串,然后在kernel32中调用WriteFile
  2. kernel32.dll实现WriteFile,注意到句柄是控制台并将调用定向到控制台系统
  3. 将字符串发送到实际承载控制台窗口的conhost.exe进程(在Windows 7上,在早期版本上为csrss.exe)
  4. conhost.exe将字符串添加到内部缓冲区,该缓冲区表示控制台窗口的内容并使控制台窗口无效
  5. 窗口管理器注意到控制台窗口现在无效并向其发送WM_PAINT消息
  6. 响应WM_PAINT,控制台窗口(仍在conhost.exe内)在GDI32.dll(或者可能是GDI +?)中进行一系列DrawString调用。
  7. DrawString方法循环遍历字符串中的每个字符,并且:
    1. 在字体文件中查找字形定义以获取字形的轮廓
    2. 以当前字体大小检查其缓存中是否存在该字形的渲染版本
    3. 如果字形不在缓存中,它会以当前字体大小光栅化轮廓并将结果缓存到以后
    4. 将光栅化字形中的像素复制到指定的图形缓冲区,逐个像素
  8. 完成所有DrawString次调用后,窗口的最终图像将被发送到DWM,并将其加载到图形卡的图形内存中,并替换旧窗口
  9. 当绘制下一帧时,图形卡现在使用新图像渲染控制台窗口并且新字符串在那里
  10. 现在我已经简化了很多层(例如,图形卡呈现内容的方式是整个'其他层次的抽象)。我可能已经犯了一些错误(我不知道Windows的实现方式很明显),但它应该会给你一个想法。

    重要的一点是,沿途的每一步都会为系统增加某种价值。

答案 1 :(得分:0)

正如codeka所说,当你调用库函数时会发生很多事情,但你需要记住的是打印字符串或显示jpeg或其他任何事情是非常复杂的。当所使用的方法必须适用于所有情况下的每个人时,情况更是如此;数百个边缘案例。

这真正意味着当你正在编写严肃的数字运算,下棋时,天气预测代码不会调用库函数。而是只使用廉价的功能,这些功能可以直接由CPU执行。另外,计划昂贵的功能可以产生巨大的差异(最后打印所有内容而不是每次都通过循环)。

答案 2 :(得分:-1)

无论有多少抽象级别都是无关紧要的,只要能够以最有效的方式完成艰苦的工作。

一般来说,你会“模仿”你的最低级别,例如:你在运行一些糟糕实现的应用程序的x86 CPU上模拟68K CPU,但它的性能不会比原始硬件差。否则你不会首先模仿它。例如。今天,大多数用户界面逻辑是使用高级动态脚本语言实现的,因为它的效率更高,而硬核内容则由优化的低级代码处理。

在性能方面,它始终是首先遇到困难的工作。介于两者之间的东西永远不会遇到性能问题。例如。一个处理2-3次按键的键处理程序,一秒钟可以在编写错误的代码中花费大量资金而不影响最终用户体验,而mpeg编码器中的运动估计器将完全失败,只需在软件中实现而不是使用专用硬件。