x86相关内容
pause 指令通常用于测试循环spinlock,当其他一些线程拥有自旋锁时,以减轻紧密循环.据说相当于一些NOP指令.有人能告诉我它究竟是如何用于自旋锁优化的吗?在我看来,即使是 NOP 指令也是浪费 CPU 时间.它们会降低 CPU 使用率吗? 另一个问题是我是否可以将暂停指令用于其他类似目的.例如,我有一个繁忙的线程,它不断扫描某些地方(例如队列)以检索新节点;然而,有时队列是空的,线
..
Linux 内核在 x86 架构上的默认内存页大小是 4 KB,我想知道它是如何计算的,为什么? 解决方案 默认页面大小由 CPU 的 MMU(内存管理单元)支持的内容决定.在 32 位保护模式下 x86 支持两种页面: 普通的,4 KiB 巨大的,4 MiB 并非所有 x86 处理器都支持大页面.需要有一个具有页面大小扩展 (PSE) 功能的 CPU.这不包括奔腾之前的处理
..
我记得在我的架构类中假设 L1 缓存命中是 1 个周期(即与寄存器访问时间相同),但在现代 x86 处理器上实际上是这样吗? L1 缓存命中需要多少个周期?与注册访问权限相比如何? 解决方案 这里有一篇关于这个主题的精彩文章: http://arstechnica.com/gadgets/reviews/2002/07/caching.ars/1 回答您的问题 - 是的,
..
我正在重新学习我在非常旧的 MS-DOS 机器上使用的汇编程序!!! 这是我对这个函数应该是什么样子的理解.当尝试将 0xffffffff 放入 ecx 时,它编译但因 SIGSEGV 而崩溃. 代码在具有 32 位 Debian 9 的 VM 中运行.任何帮助将不胜感激. int getStringLength(const char *pStr){int len = 0;字符 *
..
我试图在 Intel i3 处理器上找到 32 个元素(每个 1 字节数据)的总和减少.我是这样做的: s=0;对于 (i=0; i 但是,它需要更多时间,因为我的应用程序是一个需要更少时间的实时应用程序.请注意,最终和可能超过 255. 有没有办法使用低级 SIMD SSE2 指令来实现这一点?不幸的是,我从未使用过 SSE.为此,我尝试搜索 sse2 函数,但它也不可用.是否(sse
..
我将引导加载程序从 CHS 更改为 LBA,因此我将 int 13h 02h 替换为 int 13h 42h.它在 QEMU 中正常工作,但是,我在使用 Bochs 和我的笔记本电脑运行它时遇到了麻烦. 我使用 dd if=main.bin of=/dev/sdb bs=512 将引导加载程序写入 USB 闪存驱动器.笔记本电脑加载英特尔 UNDI 并给我以下错误:No bootable d
..
将 32 位存储在内存中的 uint32_t 中,将每一位解包到 AVX 寄存器的单独字节元素的最快方法是什么?这些位可以位于各自字节内的任何位置. 编辑:澄清一下,我的意思是位 0 到字节 0,位 1 到字节 1.显然字节中的所有其他位都为零.目前我能做的最好的是 2 PSHUFB 并且每个位置都有一个掩码寄存器. 如果uint32_t是位图,那么对应的向量元素应该是0或非0.(也就
..
多年前,我正在学习 x86 汇编器、CPU 流水线、缓存未命中、分支预测和所有爵士乐. 这是一个分为两部分的故事.我阅读了处理器中冗长管道的所有奇妙优势,即指令重新排序、缓存预加载、依赖交错等. 缺点是任何偏离规范的代价都非常大.例如,IIRC 早期千兆赫时代的某个 AMD 处理器每次通过指针 (!) 调用函数时都会受到 40 个周期 惩罚,这显然是正常的. 这不是一个可以忽略的
..
我在一个系统上观察到 std::fill 在大型 std::vector 上设置常量值时明显且始终较慢 >0 与常量值 1 或动态值相比: 5.8 GiB/s 对比 7.5 GiB/s 然而,对于较小的数据大小,结果是不同的,其中 fill(0) 更快: 如果有多个线程,在 4 GiB 数据大小时,fill(1) 显示出更高的斜率,但达到的峰值比 fill(0) (51
..
前一周,我写了一个小线程类和一个单向消息管道来允许线程之间的通信(显然,每个线程两个管道,用于双向通信).在我的 Athlon 64 X2 上一切正常,但我想知道如果两个线程都在查看同一个变量并且每个内核上该变量的本地缓存值不同步,我是否会遇到任何问题. 我知道 volatile 关键字会强制一个变量从内存中刷新,但是在多核 x86 处理器上有没有办法强制所有内核的缓存同步?这是我需要担心的
..
我开发了一个高性能 Cholesky 分解例程,它应该在单个 CPU(没有超线程)上达到大约 10.5 GFLOPs 的峰值性能.但是在我测试它的性能时,有一些我不明白的现象.在我的实验中,我测量了增加矩阵维数 N(从 250 到 10000)的性能. 在我的算法中,我应用了缓存(调整了阻塞因子),并且在计算过程中始终以单位步幅访问数据,因此缓存性能最佳;消除了 TLB 和分页问题; 我有
..
在 Ubuntu x86 系统上反汇编 ELF 二进制文件 我不禁注意到 code(.text) 部分从虚拟地址 0x8048000 开始,所有较低的内存地址似乎都未使用. 这似乎相当浪费,所有谷歌出现的要么是民间传说涉及 STACK_TOP 或防止空指针取消引用.后一种情况看起来可以通过使用单个页面而不是留下 128MB 的间隙来修复. 所以我的问题是 - 是否有明确的答案来解释为什
..
我有一个正在组装和链接的 NASM 组装文件(在 Intel-64 Linux 上). 有一个文本文件,我希望文本文件的内容出现在生成的二进制文件中(基本上是一个字符串).二进制文件是一个 ELF 可执行文件. 我的计划是在 ELF 文件中创建一个新的只读数据部分(相当于传统的 .rodata 部分). 理想情况下,应该有一个工具可以将文件逐字添加为 elf 文件中的新部分,或者
..
我最近一直在问自己一个真正的问题是什么设计选择使 x86 成为小端架构而不是大端架构? 解决方案 在很大程度上,出于同样的原因,在添加时从最低有效数字(右端)开始——因为进位会向更有效的数字传播.将最低有效字节放在最前面允许处理器在仅读取偏移量的第一个字节后开始添加. 在您完成足够多的汇编编码和调试之后,您可能会得出结论,小端不是一个奇怪的选择——我们人类使用大端很奇怪.
..
有没有办法做到这一点?我已经使用了 objdump,但它不会产生任何我知道的任何汇编程序都会接受的汇编输出.我希望能够更改可执行文件中的指令,然后再对其进行测试. 解决方案 我认为没有任何可靠的方法可以做到这一点.机器码格式非常复杂,比汇编文件还要复杂.实际上不可能采用编译后的二进制文件(例如,ELF 格式)并生成一个源汇编程序,该程序将编译为相同(或足够相似)的二进制文件.要了解差异,请
..
我正在使用 AVX 一次计算八个点积.在我当前的代码中,我做这样的事情(展开之前): 常春藤桥/桑迪桥 __m256 areg0 = _mm256_set1_ps(a[m]);for(int i=0; i
..
哪些头文件为不同的 x86 SIMD 指令集扩展(MMX、SSE、AVX 等)提供了内在函数?在网上找不到这样的列表似乎是不可能的.如果我错了,请纠正我. 解决方案 现在你通常应该只包含 .它包括一切. GCC 和 clang 将阻止您将内部函数用于编译时未启用的指令(例如使用 -march=native 或 -mavx2 -mbmi2 -mpopcnt -mfma -mcx16-m
..
在最近的英特尔 ISA 文档中,lfence 指令被定义为序列化指令流(防止其乱序执行).特别是,指令的说明包括这一行: 具体来说,LFENCE 在所有先前的指令在本地完成之前不会执行,并且在 LFENCE 完成之前不会有后续指令开始执行. 请注意,这适用于所有指令,而不仅仅是内存加载指令,使lfence 更多不仅仅是内存排序栅栏. 虽然这现在出现在 ISA 文档中,但不清楚它是
..
我一直在尝试用 Google 搜索我的问题,但老实说我不知道如何简洁地陈述问题. 假设我在多核 Intel 系统中有两个线程.这些线程在同一个 NUMA 节点上运行.假设线程 1 写入 X 一次,然后只是偶尔向前读取它.进一步假设,除其他外,线程 2 连续读取 X.如果我不使用内存栅栏,线程 1 写入 X 和线程 2 看到更新的值之间可以间隔多长时间? 我知道 X 的写入将进入存储
..
我正在寻找在 AVX 元素(单精度浮点)上运行的指数函数的有效(快速)近似.即 - __m256 _mm256_exp_ps( __m256 x ) 没有 SVML. 相对准确度应该类似于 ~1e-6 或 ~20 个尾数位(2^20 中的 1 部分). 如果它是用英特尔内在函数以 C 风格编写的,我会很高兴. 代码应该是可移植的(Windows、macOS、Linux、MSVC、IC
..