- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是一个 common claim将字节存储到缓存中可能会导致内部读取-修改-写入周期,或者以其他方式损害吞吐量或延迟,而不是存储完整的寄存器。
但我从未见过任何例子。没有 x86 CPU 是这样的,我认为所有高性能 CPU 也可以直接修改缓存行中的任何字节。如果某些微 Controller 或低端 CPU 有缓存,它们是否有所不同?
( 我不计算字可寻址机器 ,或字节可寻址但缺少字节加载/存储指令的 Alpha 。我指的是 ISA 本身支持的最窄存储指令。)
在我的研究中回答 Can modern x86 hardware not store a single byte to memory? ,我发现 Alpha AXP 省略字节存储的原因假定它们将作为真正的字节存储实现到缓存中,而不是包含单词的 RMW 更新。 (因此它会使 L1d 缓存的 ECC 保护更加昂贵,因为它需要字节粒度而不是 32 位)。
我假设在提交到 L1d 缓存期间的 word-RMW 不被视为其他最近实现字节存储的 ISA 的实现选项。
所有现代架构(除了早期的 Alpha)都可以对不可缓存的 MMIO 区域(不是 RMW 周期)进行真正的字节加载/存储,这是为具有相邻字节 I/O 寄存器的设备编写设备驱动程序所必需的。 (例如,使用外部启用/禁用信号来指定更宽总线的哪些部分保存真实数据,例如 this ColdFire CPU/microcontroller 上的 2 位 TSIZ(传输大小),或 PCI/PCIe 单字节传输,或 DDR SDRAM 控制屏蔽所选字节的信号。)
也许在缓存中为字节存储执行 RMW 循环是微 Controller 设计需要考虑的事情,即使它不是针对像 Alpha 这样的 SMP 服务器/工作站的高端超标量流水线设计?
我认为这种说法可能来自字寻址机器。或者来自需要在许多 CPU 上进行多次访问的未对齐的 32 位存储,人们错误地将其概括为字节存储。
为了清楚起见,我希望到相同地址的字节存储循环将在每次迭代中以与字存储循环相同的周期运行。因此,对于填充数组,32 位存储可以比 8 位存储快 4 倍。 (如果 32 位存储使内存带宽饱和,而 8 位存储不饱和,则可能更少。)但除非字节存储有额外的损失,否则您不会获得超过 4 倍的速度差异。 (或任何字宽)。
我说的是 asm。一个好的编译器会在 C 中自动向量化一个字节或 int 存储循环,并使用更广泛的存储或目标 ISA 上的最佳存储,如果它们是连续的。
(并且存储缓冲区中的存储合并也可能导致更广泛地提交到 L1d 缓存以获取连续的字节存储指令,因此这是微基准测试时需要注意的另一件事)
; x86-64 NASM syntax
mov rdi, rsp
; RDI holds at a 32-bit aligned address
mov ecx, 1000000000
.loop: ; do {
mov byte [rdi], al
mov byte [rdi+2], dl ; store two bytes in the same dword
; no pointer increment, this is the same 32-bit dword every time
dec ecx
jnz .loop ; }while(--ecx != 0}
mov eax,60
xor edi,edi
syscall ; x86-64 Linux sys_exit(0)
sizeof(unsigned int)
不是 2 的幂,则只有很小的偏差)。 ASM
on Godbolt for a few different ISAs ,要么不展开,要么两个版本的展开量相同。
// volatile defeats auto-vectorization
void byte_stores(volatile unsigned char *arr) {
for (int outer=0 ; outer<1000 ; outer++)
for (int i=0 ; i< 1024 ; i++) // loop over 4k * 2*sizeof(int) chars
arr[i*2*sizeof(unsigned) + 1] = 123; // touch one byte of every 2 words
}
// volatile to defeat auto-vectorization: x86 could use AVX2 vpmaskmovd
void word_stores(volatile unsigned int *arr) {
for (int outer=0 ; outer<1000 ; outer++)
for (int i=0 ; i<(1024 / sizeof(unsigned)) ; i++) // same number of chars
arr[i*2 + 0] = 123; // touch every other int
}
word_store()
比 byte_store()
快.
lb
或 lbu
加载并归零或符号扩展它,然后将其存储回 sb
. (如果您需要在寄存器中的步骤之间截断为 8 位,那么您可能需要额外的指令,因此本地变量通常应该是寄存器大小。除非您希望编译器使用具有 8 位元素的 SIMD 自动矢量化,否则通常 uint8_t本地人很好......)但无论如何,如果你做得对并且你的编译器很好,那么拥有字节数组不应该花费任何额外的指令。sizeof(uint_fast8_t) == 1
在 ARM、AArch64、x86 和 MIPS 上。但是 IDK 我们可以投入多少库存。 x86-64 System V ABI 定义了 uint_fast32_t
作为 x86-64 上的 64 位类型。如果他们打算这样做(而不是 32 位,这是 x86-64 的默认操作数大小),uint_fast8_t
也应该是 64 位类型。也许在用作数组索引时避免零扩展?如果它在寄存器中作为函数 arg 传递,因为如果您无论如何必须从内存中加载它,它可以免费进行零扩展。
最佳答案
我的猜测是错误的。现代 x86 微体系结构在这方面确实与某些(大多数?)其他 ISA 不同。
即使在高性能非 x86 CPU 上,缓存的窄存储也会受到惩罚。 缓存占用空间的减少仍然可以使 int8_t
不过值得使用的数组。 (在某些 ISA 上,例如 MIPS,不需要为寻址模式缩放索引会有所帮助)。
在实际提交到 L1d 之前,将字节存储指令之间的存储缓冲区中的存储缓冲区合并/合并到同一字也可以减少或消除惩罚。 (x86 有时不能做那么多,因为它的强内存模型要求所有存储都按程序顺序提交。)
ARM's documentation for Cortex-A15 MPCore (从 2012 年开始)说它在 L1d 中使用 32 位 ECC 粒度,并且实际上确实为窄存储做了一个 word-RMW 来更新数据。
The L1 data cache supports optional single bit correct and double bit detect error correction logic in both the tag and data arrays. The ECC granularity for the tag array is the tag for a single cache line and the ECC granularity for the data array is a 32-bit word.
Because of the ECC granularity in the data array, a write to the array cannot update a portion of a 4-byte aligned memory location because there is not enough information to calculate the new ECC value. This is the case for any store instruction that does not write one or more aligned 4-byte regions of memory. In this case, the L1 data memory system reads the existing data in the cache, merges in the modified bytes, and calculates the ECC from the merged value. The L1 memory system attempts to merge multiple stores together to meet the aligned 4-byte ECC granularity and to avoid the read-modify-write requirement.
关于performance - 是否有任何现代 CPU 的缓存字节存储实际上比字存储慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54217528/
我正在维护一些 Java 代码,我目前正在将它们转换为 C#。 Java 代码是这样做的: sendString(somedata + '\000'); 在 C# 中,我正在尝试做同样的事情: sen
如何确定函数中传递的参数是字符串还是字符(不确定如何正确调用它)文字? 我的函数(不正确): void check(const char* str) { // some code here }
我真的不知道如何准确地提出这个问题,但我希望标题已经说明了这一点。 我正在寻找一种方法(一个框架/库),它提供了执行 String.contains() 函数的能力,该函数告诉我给定的字符串是否与搜索
我正在尝试编写一些读取 Lambda 表达式并输出 beta 缩减版本的东西。 Lambda 的类型如下:\variable -> expression,应用程序的形式为 (表达式) (表达式)。因此
StackOverflow 上的第 1 篇文章,如果我没能把它做好,我深表歉意。我陷入了一个愚蠢的练习,我需要制作一个“刽子手游戏”,我尝试从“.txt”文件中读取单词,然后我得到了我的加密函数,它将
我想在 Groovy 中测试我的 Java 自定义注释,但由于字符问题而未能成功。 Groovyc: Expected 'a' to be an inline constant of type cha
当我尝试在单击按钮期间运行 javascript location.href 时,出现以下错误“字 rune 字中的字符过多”。 最佳答案 这应该使用 OnClientClick相反? 您可能还想停
我想要类似的东西: let a = ["v".utf8[0], 1, 2] 我想到的最接近的是: let a = [0x76, 1, 2] 和 "v".data(using: String.Encod
有没有办法在 MySQL 中指定 Unicode 字 rune 字? 我想用 Ascii 字符替换 Unicode 字符,如下所示: Update MyTbl Set MyFld = Replace(
阅读 PNG 规范后,我有点惊讶。我读过字 rune 字应该用像 0x41 这样的二进制值进行硬编码,而不是在(程序员友好的)'A' 中。问题似乎是在具有不同底层字符集的不同系统上编译期间字 rune
考虑一个具有 UTF-8 执行字符集的 C++11 编译器(并且符合要求 char 类型为有符号 8 位字节的 x86-64 ABI) . 字母 Ä(元音变音)具有 0xC4 的 unicode 代码
为什么即使有 UTF-8 字符串文字,C11 或 C++11 中也没有 UTF-8 字 rune 字?我知道,一般来说,字 rune 字表示单个 ASCII 字符,它与单字节 UTF-8 代码点相同,
我怎样才能用 Jade 做到这一点? how would I do this 我几乎可以做任何事情,除了引入一个 span 中间句子。 最佳答案 h3.blur. how would I do t
这似乎是一个非常简单的问题,但我只是想澄清我的疑问。我正在查看其他开发人员编写的代码。有一些涉及 float 的计算。 示例:Float fNotAvlbl = new Float(-99); 他为什
我想知道第 3 行“if dec:”中的“dec”是什么意思 1 def dec2bin(dec): 2 result='' 3 if dec:
我试图在字符串中查找不包含任何“a”字符的单词。我写了下面的代码,但它不起作用。我怎么能对正则表达式说“不包括”?我不能用“^”符号表示“不是”吗? import re string2 = "asfd
这个问题在这里已经有了答案: Is floating point math broken? (31 个答案) Is floating point arbitrary precision availa
我正在创建一个时尚的文本应用程序,但在某些地方出现错误(“字 rune 字中的字符太多”)。我只写了一个字母,但是当我粘贴它时,它会转换成许多这样的字母:“\uD83C\uDD89”,原始字母是“🆉
我正在尝试检查用户是否在文本框中输入了一个数字值,是否接受了小数位。非常感谢任何帮助。 Private Sub textbox1_AfterUpdate() If IsNumeric(textbox1
我知道一个 Byte 是 8 位,但其他的代表什么?我正在参加一个使用摩托罗拉 68k 架构的汇编类(class),我对目前的词汇感到困惑。 最佳答案 如 operator's manual for
我是一名优秀的程序员,十分优秀!