标签: intel

为什么英特尔这些年来改变了静态分支预测机制?

这里我知道英特尔近年来实施了几种静态分支预测机制:

  • 80486年龄:永远不被采取

  • Pentium4年龄:未采取后退/前锋

  • 像Ivy Bridge,Haswell这样的新型CPU变得越来越无形,请参阅Matt G的实验.

英特尔似乎不想再谈论它,因为我在英特尔文档中找到的最新资料大约是十年前写的.

我知道静态分支预测(远远不是)比动态更重要,但在很多情况下,CPU将完全丢失,程序员(使用编译器)通常是最好的指南.当然,这些情况通常不是性能瓶颈,因为一旦频繁执行分支,动态预测器就会捕获它.

由于英特尔不再在其文档中明确声明动态预测机制,因此GCC的builtin_expect()只能从热路径中删除不太可能的分支.

我不熟悉CPU的设计,我不知道究竟是什么机制,目前英特尔使用其静态预测,但我还是觉得英特尔的最佳机制应该清楚地记录他的CPU",我打算去当动态预测失败,向前或向后',因为通常程序员是当时最好的指南.

更新:
我发现你提到的主题逐渐超出我的知识范围.这里涉及一些动态预测机制和CPU内部细节,我在两三天内无法学习.所以请允许我暂时退出你的讨论并充电.
这里仍然欢迎任何答案,也许会帮助更多人

compiler-construction x86 intel cpu-architecture branch-prediction

9
推荐指数
3
解决办法
1637
查看次数

多核处理器:每个"核心"是以全时钟速度还是全时钟频率的某个部分运行?

假设你有一个(1)Intel/AMD x86-64 bit 2 GHz 8核处理器.

8个内核中的每一个都是在完整的2 GHz运行,还是每个内核运行的时间是整个2 GHz时钟的一部分(例如250 MHz)?

architecture intel microprocessors amd-processor

8
推荐指数
2
解决办法
8009
查看次数

当数据隐藏在对象内时如何使用intel prefetch pragma?

英特尔有助于提供预取编译指示; 例如

#pragma prefetch a
for(i=0; i<m; i++)
  a[i]=b[i]+1;
Run Code Online (Sandbox Code Playgroud)

将由a编译器确定预先获取一定数量的循环周期.

但是如果a不是一个数组而是一个[]被覆盖的类呢?如果operator[]一个简单的数组访问,可以预取仍然以这种方式使用?

(据推测这个问题也适用于此std::vectors).

c++ memory-management intel pragma prefetch

8
推荐指数
1
解决办法
1495
查看次数

为什么MS-DOS不初始化DS和ES寄存器?

为什么DSES寄存器的初始化必须由程序员手动完成?

例如:

MOV AX, DTSEG
MOV DS, AX
Run Code Online (Sandbox Code Playgroud)

另一方面,CSSS寄存器由操作系统(in MS-DOS)初始化.为什么会这样?

assembly dos intel masm x86-16

8
推荐指数
1
解决办法
1471
查看次数

Sandy Bridge上的32字节存储转发

在Agner Fog的优秀微体系结构中 .pdf (第9.14节)我读到:

存储转发在以下情况下有效:[...]当写入128或256位后,读取相同大小和相同的地址,对齐16.

另一方面,我阅读了英特尔架构优化参考手册(2.2.5.2 Intel Sandy Bridge,L1 DCache)

在以下情况下,存储无法转发到负载:[...]任何跨越32字节存储的16字节边界的负载.

任何负载听起来像32字节加载..我写了以下简单的代码来测试这一点,似乎32字节存储转发到Sandy Bridge架构上的后续32字节加载.这是代码:

#include <stdlib.h>
#include <malloc.h>

int main(){

  long i;

  // aligned memory address
  double *tempa = (double*)memalign(4096, sizeof(double)*4);
  for(i=0; i<4; i++) tempa[i] = 1.0;

  for(i=0; i<1000000000; i++){ // 1e9 iterations

#ifdef TEST_AVX
    __asm__("vmovapd    %%ymm12, (%0)\n\t"
            "vmovapd    (%0), %%ymm12\n\t" 
        : 
        :"r"(tempa));
#else
    __asm__("movapd %%xmm12, (%0)\n\t"
            "movapd (%0), %%xmm12\n\t"
            :
            :"r"(tempa));
#endif
  }
}
Run Code Online (Sandbox Code Playgroud)

在循环中唯一做的是从4k对齐的存储器位置和向量寄存器读取/写入.使用AVX指令集(gcc -O3 -DTEST_AVX)编译时,我的2.7GHz i7-2620M的执行时间为3.1秒.使用SSE2指令集时,时间为2.5秒.我看了一下性能指标.在AVX情况下,我计算每次迭代一次存储转发块事件(计数器03H 02H LD_BLOCKS.STORE_FORWARD).计数器为SSE2情况读取0.

任何人都可以对此有所了解吗?SB确实不支持将32字节存储转发到32字节加载吗?如果是后者,溢出ymm …

c performance assembly intel performancecounter

8
推荐指数
1
解决办法
370
查看次数

最好的方法是洗掉两个__m128i的64位部分

我有两个__m128is,a并且b,我想要洗牌,以便在64位a的低位64位dst和64位的高位b落在64位的高位64位dst.即

dst[ 0:63]  = a[64:127]
dst[64:127] = b[0:63]
Run Code Online (Sandbox Code Playgroud)

相当于:

__m128i dst = _mm_unpacklo_epi64(_mm_srli_si128i(a, 8), b);
Run Code Online (Sandbox Code Playgroud)

要么

__m128i dst = _mm_castpd_si128(mm_shuffle_pd(_mm_castsi128_pd(a),_mm_castsi128_pd(b),1));
Run Code Online (Sandbox Code Playgroud)

有没有比第一种方法更好的方法呢?第二个只是一条指令,但切换到浮点SIMD执行比第一条指令的额外指令更昂贵.

sse intel simd intrinsics

8
推荐指数
1
解决办法
768
查看次数

AVX512中的128位跨通道操作能提供更好的性能吗?

在为AVX256,AVX512和一天AVX1024设计前瞻性算法时,考虑到大SIMD宽度的完全通用置换的潜在实现复杂性/成本,我想知道即使在AVX512中通常保持隔离128位操作是否更好?

特别是考虑到AVX有128位单元来执行256位操作.

为此,我想知道在所有512位向量中AVX512置换类型操作之间是否存在性能差异,而 512位向量的每个4x128位子向量中是否存在置换类型操作?

performance x86 intel avx avx512

8
推荐指数
1
解决办法
1181
查看次数

intel core i7处理器使用哪种缓存映射技术?

我已经了解了不同的缓存映射技术,如直接映射,关联映射和集合关联映射技术,还学习了权衡.但我很好奇现在在intel core i7或AMD处理器中使用了什么.以及这些技术是如何演变的.还有哪些事情需要改进?

x86 amd intel cpu-architecture cpu-cache

8
推荐指数
1
解决办法
2255
查看次数

如果我不使用围栏,核心可以花多长时间看到另一个核心的写入?

我一直试图谷歌我的问题,但老实说,我不知道如何简洁地陈述问题.

假设我在多核Intel系统中有两个线程.这些线程在同一个NUMA节点上运行.假设线程1写入X一次,然后只是偶尔读取它向前移动.进一步假设,线程2连续读取X. 如果我不使用内存栅栏,在线程1写入X和线程2看到更新值之间可以有多长时间?

我知道X的写入将转到存储缓冲区并从那里到缓存,此时MESIF将启动,线程2将通过QPI查看更新的值.(或者至少这是我收集到的).我假设存储缓冲区将被写入存储围栏中的缓存或者是否需要重用该存储缓冲区条目,但我不知道存储缓冲区是否已分配给写入.

最终我要为自己回答的问题是,如果线程2有可能在一个相当复杂的应用程序中看到线程1的写入几秒钟而正在做其他工作.

x86 intel cpu-architecture memory-barriers lockless

8
推荐指数
1
解决办法
172
查看次数

英特尔的 CLWB 指令使缓存行无效

我正在尝试为英特尔的clwb指令找到不会使缓存行无效的配置或内存访问模式。我正在使用 NVDIMM 对 Intel Xeon Gold 5218 处理器进行测试。Linux 版本是 5.4.0-3-amd64。我尝试使用 Device?DAX 模式并直接将此字符设备映射到地址空间。我还尝试将此非易失性内存添加为新的 NUMA 节点,并使用numactl --membind命令将内存绑定到它。在这两种情况下,当我使用clwb缓存地址时,它都会被驱逐。我正在观察 PAPI 硬件计数器的驱逐,并禁用预取器。

这是我正在测试的一个简单循环。array 和 tmp 变量,都被声明为 volatile,所以加载是真正执行的。

for(int i=0; i < arr_size; i++){
    tmp = array[i];
    _mm_clwb(& array[i]);
    _mm_mfence();
    tmp = array[i];    
}
Run Code Online (Sandbox Code Playgroud)

两次读取都会导致缓存未命中。

我想知道是否还有其他人试图检测是否有某种配置或内存访问模式会在缓存中留下缓存行?

x86 intel cpu-architecture cpu-cache persistent-memory

8
推荐指数
1
解决办法
758
查看次数