- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们有一个简单的内存吞吐量基准。它所做的只是对一大块内存重复 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/
有没有一种方法我可以编写一个“工具”来分析从 C/C++ 程序生成的 x86 汇编语言并以这种方式测量性能,无论我在 1GHz 还是 3GHz 上运行它都没有关系处理器? 我在考虑更多的指令吞吐量?我
我们正在使用 NATS 并使用 3+ 节点的集群。我们有几个生产者和许多消费者。消息大小很小 (~100bytes) 但是我们的吞吐量有点高。 ~40k/秒。所有流量都在 2x10gbps 绑定(bi
我需要一些帮助才能使用 JMeter。我想记录两种不同的场景,比如点击 2 个不同的按钮。如果我尝试为 2 个用户运行,一个用户应该点击第一个按钮,另一个用户应该同时点击另一个按钮。 我知道这是基本问
在 100Gb 网络上,我创建了一个服务器来监听 4 个端口,grpc 客户端可以达到 3GB+/s 的吞吐量。然而,当服务器监听一个端口时,grpc 客户端达到了 1GB/s 的吞吐量,即使我设置了
android Handlers可行的数据IO吞吐量是多少?足以在线程之间传递原始音频或视频吗?它应该是可持续的吗? 我在 android Handler docs 中没有看到任何对此的引用, $WE
我正在使用 logstash 和 elasticsearch 构建日志系统。 RabbitMQ 用于在两个 logstash 之间排队日志消息。 消息路径如下: source log -> logst
我正在研究 .NET Core 在 Linux 机器上的性能。具体来说,确定框架本身可用的工具可能存在什么样的限制。 我一直以 ~ 50,000 pps 的价格击中盒子。到目前为止,似乎 ~ 20,0
我有一个使用 nfs 挂载的 gentoo 无盘客户端,看起来 nfs 的吞吐量很慢。 iperf 显示网络能够推送 770 Mb/s,hdparm 显示服务器上的 SATA 磁盘速度为 90 Mb/
我正在使用 Java Preferences API 来存储 Swing 应用程序的窗口位置和大小。此时此刻,我正在监听窗口调整大小/重新定位事件并在每次更改时存储位置和大小。然而,这意味着如果用户慢
我正在尝试弄清楚 DataFlow 如何扩展某些操作以及如何使其表现最佳。首先,我刚刚创建了一个简单的流程,它从 BigQuery 中读取数据(约 2500 万行,总共 30GB),进行 JSON 提
确定 Oracle Java 8 JVM 垃圾收集器吞吐量的最简单方法是什么,最好使用 JDK 命令行工具? 通过 jstat 命令,我可以获得总的垃圾收集时间(GCT 列)。根据这个值的变化与GC日
我有一个 Java 程序,它使用 HDFS 数据输入/输出流读取文件并将内容写入新文件。我的目标是找出我的 HDFS 的 I/O 吞吐量。下面是执行读/写和计时的代码片段: long start =
我了解延迟 - 消息从发件人到收件人所需的时间 - 和带宽 - 在给定时间内可以传输的最大数据量 - 但我正在努力寻找合适的术语来描述相关事物: 如果协议(protocol)是基于对话的——负载在端点
我有一个在 pesto、mod_wsgi 和 Apache 上运行的普通 WSGI 应用程序: def viewData(request): return Response("aaaaaaaa
我们计划将 10000 个 JSON 文档写入 Azure Cosmos DB (MongoDB),吞吐量单位重要吗?如果重要,我们可以增加批量负载并将其设置回较低的数字 最佳答案 是的,你可以做到。
我们计划将 10000 个 JSON 文档写入 Azure Cosmos DB (MongoDB),吞吐量单位重要吗?如果重要,我们可以增加批量负载并将其设置回较低的数字 最佳答案 是的,你可以做到。
在我的 spark 应用程序中,我正在阅读 kafka 主题。该主题有 10 个分区,因此我创建了 10 个接收器,每个接收器一个线程。通过这样的配置,我可以观察到接收器的奇怪行为。这些消费者的平均利
关于 AWS DynamoDb 吞吐量,我有些无法理解的地方。 让我们考虑强一致性读取。 现在,我明白在这种情况下,1 个容量单位意味着我每秒最多可以读取 4KB 的数据。 “每秒”这一点让我有点困惑
来自 AWS Lambda 常见问题解答: Q: Is there a limit to the number of AWS Lambda functions I can execute at onc
在内核版本 4.X 上运行 iperf tcp_ul 流量时,我观察到 tcp_ul 的吞吐量有所下降。任何人都知道,为什么会这样。 最佳答案 在内核版本 4.4 之后,他们修改了 TCP 拥塞控制算
我是一名优秀的程序员,十分优秀!