所以,这个AVX的东西-它就像一个小机器的每个核心?或者它就像整个CPU的一个引擎单元?
比如,我可以在每个核心上使用它吗?我在玩它,我觉得我可能会“过度使用”它,造成某种瓶颈。
你能给我解释一下吗?我全搞错了吗?
高级向量扩展(AVX)是指令。每个CPU都有不同的硬件来实现它们。据我所知,每个内核都有自己的硬件,用于处理与这些指令(以及其他指令)相关的所有内容,因此它们之间没有交互。
此外,内存将非常隔离,因为每个核心将在自己的一级和二级缓存上工作。第一次交互将发生在L3缓存上,这意味着在并行化(多线程软件)后,性能应该会得到提升,除非从一个处理器访问内存的方式开始与另一个处理器的访问冲突。
但我的感觉是,你在需要之前担心得太多了。
它可以以几种不同的方式实现。在大多数现代CPU上,它们在每个内核上都有一个256位AVX实现。
关于如何做到这一点,有很多微妙的细节。有些可能会执行128位进程两次。其他人在一个周期内完成,但会减慢核心频率。在所有情况下,仅仅因为它做了更多的工作,它就增加了核心的功率使用和热量输出。在超线程对上运行两个AVX处理线程可能会以半速运行,因为它们无法共享AVX单元。等
如果您正在编写速度和延迟非常重要的游戏,那么您最好的选择是测量它。要么在实验室中对许多不同类型的硬件进行基准测试,要么在游戏开始时进行快速基准测试,然后在配置中设置默认值。
也可能存在内存瓶颈。不久前,我写了一些AVX代码(只是为了好玩),达到了笔记本电脑的CPU内存带宽限制。但在Xeon上运行时没有问题。
现代CPU上的SIMD指令,如AVX vmulps ymm1、ymm2、ymm3或SSE2 pmaddwd xmm0、xmm1,仅在运行该指令的物理内核内执行。每个物理核心都有自己的执行资源,其中包括SIMD/FP执行单元。(在CPU体系结构中,标量FP通常与SIMD分组。在现代x86中,您实际上在向量寄存器的低位元素上使用SSE2或AVX指令的标量版本来进行标量FP计算。)
这就是为什么最大FLOP/s与内核数成比例:sandy bridge和haswell SSE2/AVX/AVX2的每个周期的FLOP
(甚至每个核也不只有一个“AVX单元”,例如Haswell和Zen2核都有两个256位宽的FMA单元,并且可以在更多端口上运行逐位布尔向量指令,以获得这些指令更高的每时钟吞吐量。)
CPU处理SIMD指令(几乎)与整数指令(例如add eax、ecx
)完全一样。这(以及其他原因)就是为什么x86 CPU可以以非常低的延迟有效地在整数和FP寄存器之间获取数据,对于cvttss2si eax、xmm0
(Float-
有关Intel Haswell中每个执行端口上的执行单元的图表,请参阅https://www.realworldtech.com/haswell-cpu/4/。请注意,标量整数乘法器(imul
)与vaddps
位于同一端口,因此这些指令不能在给定内核上的相同时钟周期内开始执行。(Skylake在其2个FMA单元中的任何一个上运行vaddps)。
有关CPU工作原理的更多背景信息,请参阅现代微处理器90分钟指南!。
在推土机/皮尔德里弗/蒸汽压路机/挖掘机中,每对(弱)整数内核共享一个SIMD/FP单元、L1i缓存和L2缓存。这基本上是SMT的替代方案(例如英特尔的超线程),它在所有内核都很忙的情况下具有更高的总吞吐量,但无法像单个更宽的内核那样快速运行单个线程。
因此,考虑到它们的紧密耦合,这并不是正常意义上的两个独立内核。但它也不是可以运行两个硬件线程的单个内核。这就像连体双胞胎共享他们身体的一部分。https://www.realworldtech.com/bulldozer/2/更详细地描述了它。
推土机系列代表了CPU体系结构方面的大量实验,其中许多被证明是不成功的。(就像一个具有小4k写组合缓冲区的直写L1d缓存)。AMD Zen采用了一种更为传统的设计,与Intel非常相似:与SMT完全分离的宽核,既能实现高单线程性能,又能以良好的聚合吞吐量运行大量线程。以及更传统的缓存层次结构,具有普通的回写L1d缓存。与Intel更统一的调度程序和执行端口不同,Zen将AMD的SIMD/FP与标量整数部分分离。Zen1甚至保留了AMD将256位指令拆分为2个UOP的常规技术,直到Zen1扩展了执行单元。(英特尔已经在早期的CPU(如奔腾III和奔腾M)上对SSE进行了这种拆分,但自Core 2:支持任何SIMD扩展的全宽执行单元以来,就没有这样做过。)
推土机上的SIMD/FP指令具有更高的延迟(即使对于pxor xmm0, xmm1
之类的东西,2个周期的最小延迟),但这可能是由于推土机的“速度恶魔”方法来提高时钟。在整数和FP寄存器之间获取数据的延迟尤其糟糕,例如10个周期。(但通常您不会一直来回弹跳数据,并且在FP负载的寻址模式中使用整数regs是可以的。这不是推土机系列CPU相对较慢的主要或唯一原因。)
因此,它不像rdrand eax
,它必须从所有内核共享的随机性源中提取数据,并且与普通指令相比非常慢(例如Ivy Bridge上的200个周期,更像是缓存未命中负载),因为它必须脱核。而且因为它的使用频率不足以证明构建更多硬件以使其更快(例如缓冲每个内核中的随机性)。(Ivy Bridge上RDRAND指令的延迟和吞吐量是多少?来自David Johnston,他在英特尔工作)。
问题内容: 我在SUSE Linux Enterprise 10/11计算机上。我对运行Intel处理器的计算机场进行回归分析。我的某些测试失败,因为我的工具是使用需要AVX / AVX2指令支持的库构建的。我得到一个错误。 在Linux中,是否可以使用任何命令来确定CPU代码/家族名称是什么? 我相信AVX和AVX2可以分别从Intel SandyBridge和Haswell家族获得。 问题答案
问题内容: 我需要在Java中将序数值转换为枚举值。这很简单: 该方法是隐式的,我无法找到它的源代码,因此是一个问题。 是否分配新数组?如果可以的话,第一次调用时是否应该缓存该数组?假设将非常频繁地调用转换。 问题答案: 是。 Java没有让我们创建不可修改数组的机制。因此,如果返回相同的可变数组,我们将冒有人可以为所有人更改其内容的风险。 因此,在将不可修改的数组引入Java之前,为了安全起见,
问题内容: 在ExpressJS for NodeJS中,我们可以执行以下操作: 提供所有静态CSS,JS和图像文件。我的问题是: 1)当我们这样做时,Express是否会在每次提供一种资源时自动在服务器内存中缓存文件,还是从硬盘上读取文件? 2)执行此操作时,Express是否默认使用ETag将资源保存在客户端的硬盘上或仅在客户端的内存上? 问题答案: 静态中间件不进行服务器端缓存。它使您可以执
问题内容: 您是否应该在JPA中每个表有一个存储库?如果不是,您如何解决存储库数据库中的泛型? 例如,下面是一个。它处理对对象的 CRUD 操作。如果我想让存储库也保存一个对象,我将如何更改下面的界面以容纳两个对象? 问题答案: 由于存储库是从域驱动设计派生的概念,因此考虑数据库表是错误的方法。根据定义,您可以从存储库访问聚合根。实际上,存储库正在模拟这些集合。 现在是什么形成聚合根?可能更有趣:
问题内容: 我有大约五种这样的方法,但是由于seriesColors是静态的,所以想知道上面的代码是否会导致内存泄漏。 如果存在内存泄漏,那么该如何解决? 在这两个代码中,哪一个存在严重缺陷? 问题答案: 静态变量在类的所有实例之间共享。(使用“ new”运算符创建一个实例。) 在这些示例中;使用静态(实例变量)存储颜色可能不是一个好主意,因为实例之间会相互干扰。该变量应更改为“普通”实例变量。