记忆阅读时间

Memory reading time

我听说从非缓存内存读取一个字节最多需要 50 CPU 个周期。

那么,从内存中读取 int 的时间是否是读取 char 的 4 倍,即最多 200 个周期?

如果不是,使用 *(size_t *)str 一次获取 4-8 个字符是否是个好主意,节省 150-350 CPU 个周期?我想在那种情况下字节顺序可能会成为一个问题。

还有,函数中使用的局部变量呢?它们是否都被写入注册表,或者尽可能内联,或者至少缓存在 L1 中?

I heard that reading one byte from non-cached memory can take up to 50 CPU cycles.

这将是特定 CPU 的特征,但在一般意义上,是的,从非缓存内存中读取是昂贵的。

So, does reading int from memory take 4 times as long as reading char, meaning up to 200 cycles?

您似乎假设 int 是 4 个字节宽,但事实并非如此。但不,从内存中读取四个连续字节通常不会花费四倍于读取一个字节的周期。内存通常以大于一个字节的块读取——至少是机器字大小,在具有 4 字节 ints 的机器上可能是 4——这通常也会导致整个缓存行占用内存将请求的位置周围加载到缓存中,以便后续访问附近的位置更快。

If not, is it a good idea to get 4-8 chars at a time with *(size_t *)str, saving 150-350 CPU cycles? I imagine endianness might become an issue in that case.

不,这不是个好主意。现代编译器非常擅长生成快速机器代码,现代 CPUs 和内存控制器在设计时考虑了典型的程序行为。您描述的那种微优化不太可能有助于提高性能,甚至可能会因抑制编译器为更直接编写的代码执行的优化而受到损害。

此外,如果 str 指向(输入)到 char 的数组而不是 真正的 size_t,我认为是你的本意。尽管如此,它可能会产生您期望的结果,但它也可能会做任何您不喜欢的事情,例如使程序崩溃。

Also, what about local variables used in a function? Do they all get written into registry, or get inlined if possible, or at least get cached in L1?

同样,您的编译器非常擅长生成机器代码。然而,它对局部变量的确切作用是特定于编译器的,并且可能因函数而异。无论如何,它都在您的控制范围之外。一个人用C而不是汇编来写,因为一个人想把这些考虑留给编译器。


总的来说:

  • 使用好的算法编写清晰的代码。
  • 依靠你的编译器来优化它。
  • 如果结果不够快,则对其进行分析以找到最慢的部分,然后处理这些部分。