Performance 静态类是否会导致多核系统的性能问题?

Performance 静态类是否会导致多核系统的性能问题?,performance,language-agnostic,static,class,Performance,Language Agnostic,Static,Class,前几天,我的一位同事说,使用静态类可能会导致多核系统的性能问题,因为静态实例不能在处理器缓存之间共享。是这样吗?是否有一些基准来证明这一说法?这句话是在与.Net开发(以及C#)相关的讨论中提出的,但在我看来,这似乎是一个与语言和环境无关的问题 谢谢您的评论。如果您不使用任何类型的锁或同步,那么静态与非静态不会对您的性能产生任何影响 如果您使用的是同步,那么如果所有线程都需要获得相同的锁,您可能会遇到问题,但这只是静态性的副作用,而不是静态方法的直接结果。我会向您的同事索要数据或至少是引用 问题

前几天,我的一位同事说,使用静态类可能会导致多核系统的性能问题,因为静态实例不能在处理器缓存之间共享。是这样吗?是否有一些基准来证明这一说法?这句话是在与.Net开发(以及C#)相关的讨论中提出的,但在我看来,这似乎是一个与语言和环境无关的问题


谢谢您的评论。

如果您不使用任何类型的锁或同步,那么静态与非静态不会对您的性能产生任何影响


如果您使用的是同步,那么如果所有线程都需要获得相同的锁,您可能会遇到问题,但这只是静态性的副作用,而不是静态方法的直接结果。

我会向您的同事索要数据或至少是引用

问题是,如果你有共享数据,你就有了共享数据。不管这是通过静态类公开的,一个单例(singleton)都不是很重要。如果您首先不需要共享数据,我希望您不会有一个静态类

除此之外,在任何给定的应用程序中,对于静态类中的共享数据,可能存在比处理器缓存更大的瓶颈

一如既往,首先编写最合理、可读、可维护的代码,然后确定是否存在性能瓶颈并采取相应措施。

“[a]静态实例不能在处理器缓存之间共享。是这样吗?”

那句话对我来说没有多大意义。每个处理器的专用缓存的要点是,它包含一小块内存的私有副本,因此,如果处理器正在执行某种只需要访问特定内存区域的算法,那么它就不必继续返回以访问外部内存。如果我们谈论的是静态类中的静态字段,那么这些字段的内存可能都适合于一个连续的内存块,而该内存块又适合于单个处理器(或内核)的专用缓存。但它们都有自己的缓存副本-它不是“共享的”。这就是缓存的意义所在

如果算法的工作集大于缓存,那么它将破坏该缓存。这意味着,当算法运行时,它会反复导致处理器从外部内存中提取数据,因为所有必需的数据块不会同时放入缓存。但这是一个一般性的问题,并不特别适用于静态类

我想知道您的同事是否不是在谈论性能,而是在讨论如果多个线程正在读取/写入相同的数据时是否需要应用正确的锁定?

使用任何“虚拟机”控制的语言(.NET、Java等)此控制可能委托给底层操作系统,并可能进一步委托给BIOS和其他调度控制。也就是说,在.NET和Java这两大巨头中,静态与非静态是内存问题,而不是CPU问题

重复saua的观点,对CPU的影响来自同步和线程控制,而不是访问静态信息

CPU缓存管理的问题不仅限于静态方法。一次只有一个CPU可以更新任何内存地址。虚拟机中的对象,特别是对象中的字段,是指向所述内存地址的指针。因此,即使我有一个可变对象
Foo
,在Foo上调用
setBar(true)
一次也只能在单个CPU上进行


尽管如此,.NET和Java的要点是,在证明自己有问题之前,你不应该把时间花在这些问题上,我怀疑你会这样做。

即使这是真的,我怀疑你有很多更好的方法来提高性能。当涉及到将静态更改为实例时,对于处理器缓存,您将知道您真的在突破极限。

如果多个线程正在写入该数据,您将出现缓存抖动(一个CPU缓存上的写入会使其他CPU的缓存失效)。你的朋友在技术上是正确的,但很有可能这不是你的主要瓶颈,所以没关系

如果多个线程正在读取数据,那么您的朋友就大错特错了

  • 如果在线程之间共享可变数据,则需要锁或无锁算法(不幸的是,很少可用,有时很难使用)。
    • 拥有很少的、广泛使用的、锁仲裁的资源可能会使您遇到瓶颈
    • 静态数据类似于单个实例资源
  • 因此:

    • 如果许多线程访问静态数据,而您使用锁进行仲裁,那么您的线程将为访问权而斗争

    在设计高度多线程的应用程序时,请尝试使用许多细粒度锁。拆分您的数据,这样一个线程就可以抓取一块数据并与其一起运行,希望没有其他线程需要等待它,因为它们正忙于处理自己的数据块。

    x86体系结构实现缓存侦听,以便在写入时保持数据缓存同步,如果它们恰好缓存相同的内容。。。并非所有的体系结构都是在硬件上实现的,有些体系结构依靠软件来确保这种情况永远不会发生。

    对我来说很有意义。他确实在谈论表演。那么你认为他是什么意思呢?:)在缓存之间共享一个实例意味着什么?他的意思是——如果我没有理解错的话——该类的静态实例一次只能存在于一个处理器缓存中。但这对我来说毫无意义。如果你认为BIOS涉及调度和缓存管理,你必须重新阅读很多…是的,BIOS与这里的任何事情都无关。一旦操作系统被加载,它就处于完全控制之下,它是唯一真正运行的进程,其他一切都只是存在于其边界内的抽象。是的