首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Skylake在单线程内存吞吐量方面比Broadwell-E要好得多?

问为什么Skylake在单线程内存吞吐量方面比Broadwell-E要好得多?
EN

Stack Overflow用户
提问于 2016-08-31 22:32:31
回答 2查看 3.4K关注 0票数 17

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

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

知道为什么会发生这种事吗?下面的代码是在VS2015发行版中编译的,并报告完成每个memcpy的平均时间:

64位: Skylake为2.2ms,Broadwell-E为4.5 vs

32位: Skylake 2.2ms,Broadwell-E 3.5ms .

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

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

代码语言:javascript
复制
#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();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-13 06:58:29

现代CPU上的单线程内存带宽受到从max_concurrency / latency传输到系统其余部分的L1D限制,而不是DRAM控制器瓶颈的限制。每个核心都有10个行填充缓冲区(LFBs),用于跟踪对L1D的未执行请求。(以及16个“超级队列”条目,它们跟踪到/从L2的行)。

(最新消息:实验显示,Skylake可能有12个LFB,比布罗德威尔的10个还多。)例如Fig7 in ZombieLoad论文,以及其他性能实验,包括@BeeOnRope对多个存储流的测试)

与四核或双核台式机/膝上型电脑芯片相比,英特尔的多核芯片对L3 /内存的延迟更大,因此在大型Xeon上,内存带宽实际上要糟糕得多,尽管多个线程的最大总带宽要好得多。它们在连接核心、内存控制器和系统代理(PCIe等)的环形总线上有更多的跳。

SKX (Skylake-server / AVX512,包括i9的“高端桌面”芯片)对此非常不利: L3 /内存延迟明显高于Broadwell-E / Broadwell-EP,因此单线程带宽甚至比具有相同核心计数的布罗德韦尔更糟糕。(SKX使用的是网格而不是环形总线,因为它的缩放性更好,有关这两个方面的详细信息,请参阅此。但是很明显,在新的设计中,不变的因素是不好的;也许后代将有更好的L3带宽/延迟,用于中小型核心计数。然而,私有的每核L2却高达1MiB,因此L3可能会故意慢下来省电。)

(Skylake客户端(SKL)就像在这个问题中一样,后来像卡比湖( Kaby )和咖啡湖( Coffee )这样的四/六核台式机/膝上型电脑芯片仍在使用更简单的环形总线布局。只是服务器芯片变了。我们还不知道冰湖的客户会做什么。)

一个四核或双核芯片只需要两个线程(特别是当核心+解核(L3)时钟高时)就能使其内存带宽饱和,而具有快速DDR4双通道的Skylake具有相当大的带宽。

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

也是相关的:关于内存,每个程序员都应该知道些什么? (2017年更新了哪些仍然是真实的,以及2007年那篇优秀文章中发生了什么变化)。

票数 16
EN

Stack Overflow用户

发布于 2016-09-15 18:20:39

我终于启动并运行了VTune (评估)。它给出了.602 (0到1之间)在布罗德维尔-E和.324在Skylake上的DRAM界评分,其中很大一部分的延迟来自记忆延迟。考虑到记忆棒的速度是相同的(除了在Skylake中配置的双通道和Broadwell-E中的四通道),我最好的猜测是,Skylake中的内存控制器是非常好的。

这使得购买Broadwell-E架构变得更加困难,并且要求你真的需要额外的核心来考虑它。

我还得到了L3/TLB的漏分数。在Broadwell-E上,TLB缺失计数约高20%,L3缺失计数约高36% .

我不认为这真的是“为什么”的答案,所以我不会把它标记成这样,但就像我认为我会得到一个暂时的。感谢您在此过程中提出的所有有益的意见。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39260020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档