gpt4 book ai didi

performance - 为什么 Skylake 在单线程内存吞吐量方面比 Broadwell-E 好这么多?

转载 作者:行者123 更新时间:2023-12-04 01:01:53 26 4
gpt4 key购买 nike

我们有一个简单的内存吞吐量基准。它所做的只是对一大块内存重复 memcpy。

查看几台不同机器上的结果(编译为 64 位),Skylake 机器的性能明显优于 Broadwell-E,保持操作系统(Win10-64)、处理器速度和 RAM 速度(DDR4-2133)相同。我们不是说几个百分点,而是大约 2 的因数. Skylake 配置为双 channel ,Broadwell-E 的结果对于双/三/四 channel 没有变化。

任何想法为什么会发生这种情况?以下代码在 VS2015 的 Release 中编译,并报告完成每个 memcpy 的平均时间:

64 位:Skylake 为 2.2 毫秒,Broadwell-E 为 4.5 毫秒

32 位:Skylake 为 2.2 毫秒,Broadwell-E 为 3.5 毫秒 .

通过利用多线程,我们可以在四 channel Broadwell-E 构建上获得更大的内存吞吐量,这很好,但是看到单线程内存访问的如此巨大差异令人沮丧。 关于为什么差异如此明显的任何想法?

我们还使用了各种基准测试软件,它们验证了这个简单示例所显示的内容 - Skylake 上的单线程内存吞吐量要好得多。

#include <memory>
#include <Windows.h>
#include <iostream>

//Prevent the memcpy from being optimized out of the for loop
_declspec(noinline) void MemoryCopy(void *destinationMemoryBlock, void *sourceMemoryBlock, size_t size)
{
memcpy(destinationMemoryBlock, sourceMemoryBlock, size);
}

int main()
{
const int SIZE_OF_BLOCKS = 25000000;
const int NUMBER_ITERATIONS = 100;
void* sourceMemoryBlock = malloc(SIZE_OF_BLOCKS);
void* destinationMemoryBlock = malloc(SIZE_OF_BLOCKS);
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
while (true)
{
LONGLONG total = 0;
LONGLONG max = 0;
LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
for (int i = 0; i < NUMBER_ITERATIONS; ++i)
{
QueryPerformanceCounter(&StartingTime);
MemoryCopy(destinationMemoryBlock, sourceMemoryBlock, SIZE_OF_BLOCKS);
QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
total += ElapsedMicroseconds.QuadPart;
max = max(ElapsedMicroseconds.QuadPart, max);
}
std::cout << "Average is " << total*1.0 / NUMBER_ITERATIONS / 1000.0 << "ms" << std::endl;
std::cout << "Max is " << max / 1000.0 << "ms" << std::endl;
}
getchar();
}

最佳答案

现代 CPU 上的单线程内存带宽受限于 max_concurrency / latency从 L1D 到系统其余部分的传输,而不是由于 DRAM Controller 瓶颈。每个内核都有 10 个行填充缓冲区 (LFB),用于跟踪到/来自 L1D 的未完成请求。 (以及 16 个“ super 队列”条目,用于跟踪往返 L2 的线路)。

(更新:实验表明 Skylake 可能有 12 个 LFB,高于 Broadwell 的 10 个。例如 the ZombieLoad paper 中的图 7,以及包括 @BeeOnRope's testing of multiple store streams 在内的其他性能实验)

Intel的多核芯片对L3/内存的延迟比四核或双核台式机/笔记本芯片要高,所以单线程内存带宽其实差很多在大型 Xeon 上,即使具有许多线程的最大聚合带宽要好得多。它们在连接核心、内存 Controller 和系统代理(PCIe 等)的环形总线上有更多的跃点。

SKX(Skylake-server/AVX512,包括i9“高端桌面”芯片)对此真的很糟糕:L3/内存延迟明显高于Broadwell-E/Broadwell-EP,因此单线程带宽更差比在具有相似核心数的 Broadwell 上。 (SKX 使用网状网络而不是环形总线,因为它可以更好地扩展,see this for details on both。但显然,新设计中的常量因素很糟糕;也许 future 的几代人对于中小型核心数量会有更好的 L3 带宽/延迟。私有(private)不过,每核 L2 高达 1MiB,因此 L3 可能故意放慢速度以节省电力。)

(问题中的 Skylake-client (SKL),以及后来的四核/六核台式机/笔记本电脑芯片,如 Kaby Lake 和 Coffee Lake,仍然使用更简单的环形总线布局。只有服务器芯片发生了变化。我们还没有肯定知道 Ice Lake 客户端会做什么。)

四核或双核芯片只需要几个线程(特别是如果核心 + 非核心 (L3) 时钟频率很高)来饱和其内存带宽,而具有快速 DDR4 双 channel 的 Skylake 具有相当多的带宽。

有关这方面的更多信息,请参阅 this answer 的延迟绑定(bind)平台部分。关于 x86 内存带宽。 (并使用 SIMD 循环与 rep movs/rep stos 以及 NT 存储与常规 RFO 存储等阅读 memcpy/memset 的其他部分。)

还相关:What Every Programmer Should Know About Memory? (2017 年更新关于 2007 年那篇优秀文章中仍然正确的内容和发生的变化)。

关于performance - 为什么 Skylake 在单线程内存吞吐量方面比 Broadwell-E 好这么多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39260020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com