我理解访问内存意味着什么是对齐但我不明白为什么这是必要的.例如,为什么我可以从一个地址访问一个字节,0x…1但是我不能从同一个地址访问一个半字(两个字节).
同样,我理解如果你有一个地址A和一个大小的对象,s访问是对齐的A mod s = 0.但我只是不明白为什么这在硬件层面很重要.
我正在阅读这个问题,我想更多地询问他展示的代码,即
for(i = 0; i < 20; i++)
for(j = 0; j < 10; j++)
a[i] = a[i]*j;
Run Code Online (Sandbox Code Playgroud)
问题是,
那个人说,
"内部循环在访问[i]十次时会调用相同的内存地址,这是我猜的时间局部性的一个例子.但是在上面的循环中是否还有空间局部性?"
我不同意他的猜测.由[a]生成的引用应该是空间局部性(它们将引用块中的下一个元素).我对吗?
我试图了解虚拟机监视器(VMM)如何虚拟化CPU.
我现在的理解是,当CPU处于用户模式时,即将执行特权指令时,CPU会发出保护错误中断.在像C这样的高级语言中,特权指令包含在系统调用中.例如,当应用程序需要当前日期和时间(与I/O设备交互的指令具有特权)时,它会调用某个库函数.此库函数的汇编版本包含一个名为"int"的指令,该指令会在CPU中生成陷阱.CPU从用户模式切换到特权模式,并跳转到操作系统提供的陷阱处理程序.每个系统调用都有自己的陷阱处理程序.在此示例中,陷阱处理程序从硬件时钟读取日期和时间并返回,然后CPU将自身从特权模式切换到用户模式.(来源:http://elvis.rowan.edu/~hartley/Courses/OperatingSystems/Handouts/030Syscalls.html)
但是,我不太确定这种理解是否正确.本文提到的(特权)的x86指令POPF不会导致陷阱的概念,从而为VMM复杂的事情:http://www.csd.uwo.ca/courses/CS843a/papers/intro-vm.pdf.根据我的理解,当用户程序显式调用而不是通过系统调用时,popf指令不应该导致陷阱,而应该导致保护错误中断.
所以我的两个具体问题是:
C++中的变量存储在哪里?
在RAM或处理器的缓存中?
有点令人困惑的问题.但我真的在寻找学习一些低级编程.事情是,开发板像Arduino/Etc.真的隐藏了很多正在发生的事情.
我花了一些时间学习计算机体系结构,逻辑/门/顺序逻辑/等等.(我甚至去了解与半导体和电子相关的物理学,只是为了知道到底发生了什么,就像以及如何使用CMOS晶体管等制造盖茨.
但那就是它结束的地方......我希望能够理解一个指令(如Hex /或汇编/等等代码)是如何通过一台简单的计算机(我用过的很多书)直接从盖茨到计算机....没有真正的介于两者之间).甚至是简单的东西.....将值存储在寄存器或存储器位置(并且可能打印到像素?或某些东西).
我认为最有趣的事情可能是最终编写模拟器.我有使用高级语言的经验,但我听说像6502这样的东西可能是一个好的开始,因为你使用了很多汇编,并且指令集不是太大.
有谁知道任何可能有帮助的资源/想法/书籍?我已经阅读了"计算系统的元素",虽然......这是一本很好的书,我真的不觉得它真的发生了什么,看到它发生了.这可能更像是一个Electronics.stackexchange问题,如果是这样,我道歉.
我一直想弄清楚我想在以后的生活中使用什么计算机领域.大学就在我身边,我考虑过从事计算机工程,软件工程等方面的工作.
最近,我一直在研究计算机安全系统和这些的开发(纯粹用于教育目的,在我自己的财产上).不幸的是,在我看来,99%的人不知道他们在谈论什么.通常情况下,它只是"运行这个"或"运行那个"或"你可以找到一个能为你完成所有这些工作的程序" - 没有人知道这些程序是如何工作的,或者它们究竟是做什么的.
我觉得使用其他人创造的东西并不像大多数人那样称自己为"黑客".事实上,我对黑客攻击系统的兴趣与他们如何做到这一点一样.
我的问题都归结于此.
我想学习计算机的内部,外部,起点和下降 - 从互联网和数据传输等抽象概念到硬件.我想知道计算机如何存储数据(如何组织叮咬等)以及处理器等实际执行的操作.什么是WIFI,真的吗?计算机是否与光通信(我从飞机上阅读的杂志中读取的东西).
我有多年的计算机/编程经验,但我对计算机的了解非常广泛.计算机在彼此之间来回发送信息包,每个信息包都有标题和内容.计算机由多个组件组成,每个组件都有自己的功能(处理器,视频卡,RAM,硬盘驱动器等),我已经对它有了一些基本的了解.等等
计算机有这么多,我不知道从哪里开始.我相信我的一些大学课程会为我解决问题,但我很好奇,我想尽可能多地开始学习.
这个问题可能到处都是,所以请在必要时请我澄清.我现在有点急躁,但我试图以最快,最连贯的方式写出我的想法(尽管我可能在这个过程中完全失败了).
提前感谢任何建议!
Justian Meyer
请随意编辑此问题的标签.目前的可怕.
编辑:
所有这些评论让我兴奋:).这么多要学习,这么多探索:).
当我objdump -D用来反汇编二进制时,典型的代码jmpq就像e9 7f fe ff ff是,用于表示负偏移.但是,x86-64的地址是64(48)位(据我所知),那么这个32位地址如何7f fe ff ff表示64位绝对地址的负偏移?
此外,还有像任何其他指令jmp和jmpq,但有64位地址位移?我怎样才能找到英特尔或AMD手册中的说明(我搜索jmpq但没有找到任何内容)?
当我搜索时,它似乎被称为RIP相对寻址.似乎并非所有说明都这样做.是否有64位相对寻址?如果是间接跳转,64位绝对地址将在寄存器或内存中,对吧?
我一直在寻找一些好的链接/来源来帮助理解GPIO以及它们在嵌入式系统中使用的原因.有谁能指点我一些?
我基本上需要一些帮助来解释/确认一些实验结果.
基础理论
关于DVFS的论文中表达的一个常见想法是执行时间具有片上和片外组件.执行时间的片上组件与CPU频率成线性关系,而片外组件保持不受影响.
因此,对于CPU绑定应用程序,CPU频率和指令退出率之间存在线性关系.另一方面,对于经常错过高速缓存并且必须频繁访问DRAM的内存绑定应用程序,关系应该是仿射的(一个不仅是另一个的倍数,还必须添加常量).
实验
我正在做实验,看看CPU频率如何在不同的内存限制水平下影响指令退出率和执行时间.
我在C中编写了一个遍历链表的测试应用程序.我有效地创建了一个链表,其各个节点的大小等于缓存行的大小(64字节).我分配了大量内存,这是缓存行大小的倍数.
链表是循环的,使得最后一个元素链接到第一个元素.此外,该链表随机遍历分配的内存中的高速缓存行大小的块.访问分配的内存中的每个缓存行大小的块,并且不会多次访问任何块.
由于随机遍历,我认为硬件不应该使用任何预取.基本上,通过遍历列表,您有一系列内存访问,没有步幅模式,没有时间局部性,也没有空间局部性.此外,因为这是一个链接列表,所以只有一个内存访问才能在前一个内存访问完成之前开始.因此,存储器访问不应该是可并行化的.
当分配的内存量足够小时,除了初始预热之外,您应该没有缓存未命中.在这种情况下,工作负载实际上受CPU限制,并且指令退出率与CPU频率非常干净地扩展.
当分配的内存量足够大(大于LLC)时,您应该错过缓存.工作负载受内存限制,指令退出率也不应随CPU频率而扩展.
基本的实验设置与此处描述的类似:" 实际CPU频率与Linux报告的CPU频率"cpufreq"子系统 ".
上述应用程序重复运行一段时间.在持续时间的开始和结束时,对硬件性能计数器进行采样,以确定在该持续时间内退出的指令数.也测量持续时间的长度.平均指令退休率是以这两个值之间的比率来衡量的.
使用Linux中的"用户空间"CPU频率调控器在所有可能的CPU频率设置中重复此实验.此外,如上所述,对CPU绑定的情况和存储器绑定的情况重复该实验.
结果
下面两个图分别显示了CPU绑定情况和内存绑定情况的结果.在x轴上,CPU时钟频率以GHz为单位指定.在y轴上,指令退出率以(1/ns)指定.
放置标记物以重复上述实验.该行显示如果指令退出率以与CPU频率相同的速率增加并通过最低频率标记,结果将是什么.
CPU绑定案例的结果.
内存限制案例的结果.
结果对CPU绑定的情况有意义,但对于内存限制的情况则没有那么多.内存限制的所有标记都低于预期的行,因为指令退出率不应该以与内存绑定应用程序的CPU频率相同的速率增加.标记似乎落在直线上,这也是预期的.
但是,随着CPU频率的变化,指令退出率似乎会发生阶跃变化.
题
是什么导致指令退休率的步骤变化?我能想到的唯一解释是内存控制器以某种方式通过内存请求速率的变化来改变内存的速度和功耗.(随着指令退出率的增加,内存请求的速率也应该增加.)这是正确的解释吗?
memory performance ram computer-architecture power-management