为什么Skylake比Broadwell-E在单线程内存吞吐量方面要好得多?
我们有一个简单的内存吞吐量基准。对于大块内存,它所做的只是重复记忆。
在几台不同的机器上查看结果(针对64位编译),Skylake机器的性能明显优于Broadwell-E,保持OS(Win10-64),处理器速度和RAM速度(DDR4-2133)相同。我们不是说几个百分点,而是大约2个因素。Skylake配置为双通道,Broadwell-E的结果不会因双/三/四通道而异。
任何想法为什么会这样?随后的代码在VS2015的Release中编译,并报告完成每个memcpy的平均时间:
64位:Skylake为2.2ms,Broadwell-E为4.5ms
32位:Skylake为2.2ms,Broadwell-E为3.5ms。
通过利用多个线程,我们可以在四通道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();}
ibeautiful