相关疑难解决方法(0)

英特尔Skylake上的商店循环出乎意料的糟糕和奇怪的双峰性能

我看到一个简单的存储循环出乎意料地表现不佳,这个存储循环有两个存储:一个具有16字节的正向步长,另一个总是位于同一位置1,如下所示:

volatile uint32_t value;

void weirdo_cpp(size_t iters, uint32_t* output) {

    uint32_t x = value;
    uint32_t          *rdx = output;
    volatile uint32_t *rsi = output;
    do {
        *rdx    = x;
        *rsi = x;

        rdx += 4;  // 16 byte stride
    } while (--iters > 0);
}
Run Code Online (Sandbox Code Playgroud)

在汇编这个循环可能3看起来像:

weirdo_cpp:

...

align 16
.top:
    mov    [rdx], eax  ; stride 16
    mov    [rsi], eax  ; never changes

    add    rdx, 16

    dec    rdi
    jne    .top

    ret
Run Code Online (Sandbox Code Playgroud)

当访问的存储区域在L2中时,我希望每次迭代运行少于3个周期.第二个商店只是一直在同一个位置,应该添加一个周期.第一个商店意味着从L2引入一条线,因此每4次迭代也会驱逐一条线.我不确定你如何评估L2成本,但即使你保守估计L1只能在每个周期中执行以下操作之一:(a)提交商店或(b)从L2接收一行或(c)将一条线驱逐到L2,对于stride-16商店流,你会得到1 + 0.25 + …

optimization performance x86 assembly x86-64

25
推荐指数
2
解决办法
1629
查看次数

L2 TLB未命中后会发生什么?

我很难理解当翻译旁视缓冲区的前两个级别导致未命中时会发生什么?

我不确定特殊硬件电路中是否出现"页面行走",或者页表是否存储在L2/L3高速缓存中,或者它们是否只存在于主存储器中.

cpu performance x86 cpu-architecture tlb

19
推荐指数
1
解决办法
2135
查看次数

为什么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, …
Run Code Online (Sandbox Code Playgroud)

performance benchmarking x86 intel cpu-architecture

12
推荐指数
1
解决办法
1594
查看次数

SIMD指令降低CPU频率

我读了这篇文章。它谈到了为什么AVX-512指令:

英特尔最新的处理器具有高级指令(AVX-512),这可能会导致内核或其他CPU的运行速度变慢,这是因为它们使用了多少电量。

我认为在Agner的博客上也提到了类似的内容(但我找不到确切的帖子)。

我想知道Skylake支持的其他哪些指令会产生类似的效果,即它们会降低功耗以在以后最大化吞吐量吗?所有前缀v指令(如vmovapdvmulpdvaddpdvsubpdvfmadd213pd)?

我正在尝试编译说明列表,以避免在为Xeon Skylake编译C ++应用程序时避免。

optimization x86 intel compiler-optimization avx512

12
推荐指数
2
解决办法
564
查看次数

现代处理器上的并行内存访问

我有一个最近的12核Intel CPU(Haswell架构),它有4个内存通道.机器可以并行执行多少次DRAM内存访问?

例如,如果我有一个使用12个线程的程序,这些线程位于紧密循环中,从一个范围太大而无法容纳缓存的随机存储器地址读取单个字节.我希望所有12个线程将花费几乎所有时间等待内存提取.

线程是否必须轮流使用DRAM总线?

注意:假设我使用的是1 GB的VM页面大小,因此没有TLB缓存未命中.

memory parallel-processing x86 multicore bus

9
推荐指数
1
解决办法
1688
查看次数

禁用所有 AVX512 扩展

我需要禁用 gcc 编译的代码中的所有 AVX512 扩展。原因是 Valgrind 在 AVX512 指令上卡住了。有没有办法用一个标志来做到这一点?

我知道如何单独禁用每个扩展(-mno-avx512f-mno-avx512pf),但这很麻烦,因为不同的 gcc 版本支持这些扩展的不同子集。

我使用CMake。如果有一种方法可以使用 CMake 机器自动化标记,这也对我有用。

gcc instruction-set avx avx512

5
推荐指数
1
解决办法
5787
查看次数

不同级别的缓存是否在同一个频域中运行?

较大的高速缓存通常具有较长的位线或字线,因此很可能具有更高的访问延迟和周期时间。

那么,L2 缓存是否与 L1 缓存在同一个域中工作?L3 缓存(切片)如何,因为它们现在是非包容性的并且在所有内核之间共享?

相关问题是:内核中的所有功能单元都在同一个时钟域中吗?非核心部分是否都在同一个时钟域中?多核系统中的内核是否同步?

我相信时钟域交叉会引入额外的延迟。CPU 芯片中的大部分部件是否在同一时钟域上工作?

cpu caching cpu-architecture

4
推荐指数
1
解决办法
342
查看次数