小编bho*_*ath的帖子

如何在Linux核心i3/i7中击败硬件预取器

我试图找到一种方法来打败H/W预取器来检测流模式并以随机顺序访问4KB数据,这样就不会被H/W预取器检测和预取.

最初我想以随机模式访问所有偶数索引数据,因为H/W预取器总是预取下一个缓存行(所以当我访问偶数索引时,下一个奇数索引数据已被预取).

我编写代码以随机模式访问所有偶数索引数据,但结果表明预取器检测到模式(不知道如何?没有固定步幅,都是随机步幅)

我正在调查原因 - 为什么会发生这种情况,然后我在英特尔发现了这篇文章; https://software.intel.com/en-us/forums/topic/473493

根据John D. McCalpin博士的说法,"带宽博士,

在"Intel 64和IA-32架构优化参考手册"(文档248966-028,2013年7月)的第2.2.5.4节中,它指出,

流式传输器预取器"[d]检测并维护多达32个数据访问流.对于每个4K字节页面,您可以维护一个前向流和一个后向流.

这意味着L2硬件预取器跟踪最近访问的16个4KiB页面,并记住这些页面的足够访问模式以跟踪一个前向流和一个后向流.因此,要通过"随机"提取来击败L2流式传输器预取器,只需确保在对先前引用的页面进行第二次引用之前访问超过15个其他4 KiB页面.因此,"随机"提取序列可以由超过16个4个KiB页码的随机排列组成,每个页面内具有随机偏移.(我的排列列表通常至少使用32页.)

所以这意味着在访问相同4KB页面的两个不同随机索引之间,我们需要访问至少16个4KB页面来击败H/W预取器.

我已经实现了John D. McCalpin建议的概念,但结果再次表明h/w预取器没有被击败.它能够检测一些模式和预取数据(参见示例输出).我有20-40个4KB页面的不同访问页数,但结果没有改进/变化.

这是我的代码:

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sched.h>

#ifndef _POSIX_THREAD_PROCESS_SHARED
#error This system does not support process shared mutex
#endif

#define MAX_COUNT 3000
#define INDEX (40*1024) // size of DUMMY 40 4KB pages

inline void clflush(volatile void *p)
{
    asm volatile ("clflush (%0)" :: "r"(p));
}

unsigned long probe(char *adrs) {
  volatile unsigned long …
Run Code Online (Sandbox Code Playgroud)

c linux optimization assembly

10
推荐指数
1
解决办法
557
查看次数

不同的进程是否具有共享静态变量或通用副本的单独副本?

我试图理解共享内存概念的基础.我试图创建一个具有一个函数和一个STATIC数组变量的共享库.我想通过该共享库的功能访问静态数组变量.

这是我的共享库

     //foo.c    
     #include <stdio.h>

    static int DATA[1024]={1 ,2 ,3 ,...., 1024};
    inline void foo(void)
    {
        int j, k=0;
        for(j=0;j<1024;j++)
        {
            k=DATA[j];
       }
        k+=0;    
    }
Run Code Online (Sandbox Code Playgroud)

我已按照共享库中的说明创建了共享库对象(libfoo.so)

现在我的问题是

1>如果我从两个不同的程序(program1和program2)访问foo(),那么program1和program2会有单独的foo()函数副本吗?

2> program1和program2 会有单独的静态DATA数组副本吗?

3>它们会加载到相同的物理内存位置吗?如果单独加载静态DATA数组,有没有办法强制/加载到相同的内存位置?

4>有没有办法找到为program1和program2存储静态DATA数组的位置?

我在linux下使用gcc.任何帮助将受到高度赞赏.谢谢.

c linux shared-libraries shared-memory

7
推荐指数
1
解决办法
3468
查看次数

如何在Linux中完成CPU分配?线程级别或进程级别?

我试图了解CPU如何在具有不同线程的不同进程之间分配.我有两个程序Program1和Program2.

Program1有5个线程,而Program2只有主线程.

情景-1:

terminal-1 :  ./Program1 
terminal-2 :  ./Program2 
Run Code Online (Sandbox Code Playgroud)

当我在一个终端中运行Program1而在另一个终端中运行Program2时,对于Program1,CPU分配为50%,对于Program2,CPU分配为50%.Program1的每个线程都获得10%(Program1累积50%)

这表明,无论进程具有什么线程,每个进程都将获得相同的CPU份额.这表明CPU分配是在进程级别完成的.

pstree显示

??bash???P1???5*[{P1}]
??bash???P2???{P2}
Run Code Online (Sandbox Code Playgroud)

情景-2:

terminal-1 : ./Program1 &  ./Program2
Run Code Online (Sandbox Code Playgroud)

当我在SAME终端中运行Program1和Program2时,对于Program1和Program2的所有线程,CPU分配都是相同的.这意味着Program1的每个线程几乎达到17%(累计Program1达到83%),Program2也达到17%.这表明CPU分配是在线程级别完成的.

pstree显示

 ??bash???P1???5*[{P1}]
 ?      ??P2
Run Code Online (Sandbox Code Playgroud)

我使用的是Ubuntu 12.04.4 LTS,kernel-config-3.11.0-15-generic.我也使用了Ubuntu 14.04.4,kernel-3.16.x并得到了类似的结果.

任何人都可以解释一下LINUX KERNEL的CPU调度程序如何区分SCENARIO-1和SCENARIO-2?

我认为CPU调度程序在分配CPU之前在某处区分SCENARIO.要了解CPU调度程序如何区分SCENARIO-1和SCENARIO-2,我已经下载了Linux内核源代码.
但是,我没有在源代码中找到区分SCENARIO-1和SCENARIO-2的地方. 如果有人向我指出CPU调度程序区分SCENARIO-1和SCENARIO-2的源代码或函数,那将会很棒.

提前致谢.

注意:虽然Ubuntu基于Debian,但令人惊讶的是,在Debian 8(kernel-3.16.0-4-686-pae)中,两个SCENARIO的CPU分配都是在Thread级别完成的,这意味着Program1的每个线程都接近17%(累计为Program1)获得83%),而Program2也获得17%.

这是代码:Program1(有5个线程)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// Let us create a global variable to change it in threads
int g = 0;

// The function to be executed by all threads
void *myThreadFun(void *vargp)
{

    // Store the value …
Run Code Online (Sandbox Code Playgroud)

c linux performance multithreading linux-kernel

7
推荐指数
1
解决办法
670
查看次数

无法在Core i7中禁用硬件预取程序

尝试在我的Core i7系统中禁用硬件预取程序时,我收到错误.我按照链接按照方法如何以编程方式禁用硬件预取?

在我的系统中

grep -i msr/boot/config - $(uname -r)

CONFIG_X86_DEBUGCTLMSR = Y

CONFIG_X86_MSR = Y

CONFIG_SCSI_ARCMSR =米

这是我的错误消息

root @ ./rdmsr 0x1a0

850089

[root @ ./wrmsr -p 0 0x1a0 0x850289(禁用Core i7中的硬件预取器)

wrmsr:pwrite:输入/输出错误

我在禁用Adjacent cache line prefetcher时收到同样的错误

知道如何解决这个问题吗?提前致谢 .

linux cpu-architecture prefetch microprocessors msr

6
推荐指数
2
解决办法
2369
查看次数

包容性还是排他性?Intel Core IvyBridge处理器中的L1,L2缓存

我有Intel Core IvyBridge处理器,Intel®Core™i7-3770 CPU @ 3.40GHz(L1-32KB,L2-256KB,L3-8MB)。我知道L3具有包容性,并且在多个内核之间共享。我想了解有关我的系统的以下内容

第1部分 :

  1. L1是包含性还是排他性?
  2. L2是包含性还是排他性?

第2部分 :

如果L1和L2都包括在内,则为了找到L2的访问时间,我们首先声明一个大小大于L2高速缓存(256KB)的数组(1MB),然后开始访问整个数组以加载到L2高速缓存中。之后,由于缓存行大小为64B,所以我们以64B的步长从开始索引到结束索引访问数组元素。为了获得更好的准确结果,我们重复此过程(访问索引处index,开始到末尾的数组元素)多次,比如说进行一百万次并取平均值。

我的理解为什么这种方法会给出正确的结果,如下所示:当我们访问大小大于L2缓存大小的数组时,整个数组将从主内存加载到L3,然后从L3加载到L2,再从L2加载到L1。整个数组的最后32KB位于L1中,因为最近已对其进行了访问。由于具有包容性和高速缓存一致性,整个阵列也存在于L2和L3高速缓存中。现在,当我从起始索引再次开始访问数组时,起始索引不在 L1高速缓存中,而是在L2高速缓存中,因此将出现高速缓存未命中,并且将从L2高速缓存中加载它。这样,整个数组的所有元素将需要更长的访问时间,总的来说,我将获得整个数组的总访问时间。要获得单次访问权限,我将获得总访问次数的平均值。

我的问题是- 我正确吗?

提前致谢 。

c processor cpu-architecture cpu-cache

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

DCU预取器在哪种情况下开始预取?

我正在阅读有关Intel Core i7系统中可用的不同预取器的信息。我进行了实验,以了解何时调用这些预取器。

这些是我的发现

  1. L1 IP预取器在3次高速缓存未命中后开始预取。它仅在缓存命中时预取。

  2. L2相邻行预取器在第一个高速缓存未命中后开始预取,并在高速缓存未命中时预取。

  3. L1 H / W(跨步)预取器在第一次高速缓存未命中后开始预取,并在高速缓存命中时进行预取。

我无法了解DCU预取器的行为。它何时开始预取或调用?它是否在缓存命中或未命中时预取下一个缓存行?

我在其中提到的英特尔文档披露-hw-prefetcher中进行了探索-DCU预取器将下一个缓存行提取到L1-D缓存中,但是在开始预取时没有明确的信息。

谁能解释DCU预取器何时开始预取?

x86 intel cpu-architecture prefetch cpu-cache

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

与单个进程方案相比,多进程方案中的访问时间意外较低

我从program1访问共享库(共享数组数据结构),并找到读取该数组的所有元素的访问时间.我得到大约17000个滴答,而只有Program1单独执行.

现在,当我首先在另一个选项卡中执行program2(具有空的while循环以保持终止)时,然后运行program1并测量访问时间以读取该数组的所有元素.令我惊讶的是,与之前只有Program1执行的场景相比,我获得了8000ticks.

看起来只有program1执行时才需要花费更多时间来读取数组,而有2个程序时,program1正在执行与之前相同的任务,而program2通过while循环使CPU保持忙碌状态.预计存在program1的访问时间会更长,而实际结果则相反.

为什么会这样?

这是共享库

#include <stdio.h> 
static const int DATA[1024]={1 ,2 ,3,.....1024];
inline void foo(void)
{
    int j, k=0,count=0;

    for(j=0;j<1024;j++)
      {
        k=DATA[j];
      }

    k+=0;    
}
Run Code Online (Sandbox Code Playgroud)

PROGRAM1

   int main(void)
    {    
    foo();

    start=timer();
    foo();
    end=timer();
    printf("Time1=%llu\n",end-start);    

    start=timer();
    foo();
    end=timer();
    printf("Time2=%llu\n",end-start);    


    start=timer();
    foo();
    end=timer();
    printf("Time3=%llu\n",end-start); 
    sleep(1);

    start=timer();
    foo();
    end=timer();
    printf("after sleep(1)\n");
    printf("Time4=%llu\n",end-start);    

    start=timer();
    foo();
    end=timer();
    printf("Time5=%llu\n",end-start);    

    sleep(2); 
    start=timer();
    foo();
    end=timer();
    printf("after sleep(2)\n");
    printf("Time6=%llu\n",end-start);    

    return 0;
    }
Run Code Online (Sandbox Code Playgroud)

程序2

   int main(void)
    {
    while(1)
        {}        
    return 0;
    }
Run Code Online (Sandbox Code Playgroud)

CASE1(仅运行Program1)

产量

Time1=17918
Time2=17672  
Time3=17816  

after sleep(1) …
Run Code Online (Sandbox Code Playgroud)

c performance gcc cpu-architecture performance-testing

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

最新处理器不支持SSSE3指令?

是否有任何仍然相关的CPU(Intel/AMD/Atom)不支持SSSE3指令?

没有SSSE3的最新CPU是什么?

x86 processor simd instruction-set

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

在英特尔酷睿i3/i7的情况下从高速缓存设置中逐出数据之后的数据

L1/L2缓存包含在Intel和L1/L2缓存中是8路相关性,意味着在一组中存在8条不同的缓存线.缓存行作为一个整体操作,意味着如果我想从缓存行中删除几个字节,整个缓存行将被删除,而不是我想要删除的那些字节.我对吗 ?

现在,我的问题是,无论是通过某个其他进程还是使用clflush(手动逐出缓存行/块),从缓存中删除/逐出集合的缓存行,系统是否会将该缓存行的驱逐数据存储在某处(在任何缓冲区,寄存器等),以便下次它可以从该位置加载数据以减少延迟,与从主存储器或更高级别的缓存加载数据相比,或者总是使缓存中的数据无效并且下次加载下一个更高级别的数据.

任何建议或文章的任何链接将受到高度赞赏.提前致谢.

architecture operating-system processor cpu-architecture computer-architecture

3
推荐指数
1
解决办法
743
查看次数

错误:'AES_BLOCK_SIZE'未声明.无法在Linux中使用C编译OpenSSL

我已经安装了最新版本的OpenSSL.我只是尝试编译并运行OpenSSL_aes程序.

在使用gcc -Wall openssl_aes.c -lcrypto进行编译时出现以下错误.我尽力解决了这个问题,但无法解决这个编译错误.

openssl_aes.c: In function ‘aes_encrypt’:
openssl_aes.c:51:22: error: ‘AES_BLOCK_SIZE’ undeclared (first use in this function)
   int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
                      ^
openssl_aes.c:51:22: note: each undeclared identifier is reported only once for each function it appears in
openssl_aes.c: In function ‘aes_decrypt’:
openssl_aes.c:75:45: error: ‘AES_BLOCK_SIZE’ undeclared (first use in this function)
   unsigned char *plaintext = malloc(p_len + AES_BLOCK_SIZE);
                                             ^
Run Code Online (Sandbox Code Playgroud)

编辑:

当我#include<openssl/aes.h>按照@ martin 添加时,编译问题就解决了.

现在,gcc -Wall openssl_aes.c -lcrypto已成功编译.

但是,当我尝试运行程序(运行我使用 - ./a.out)时,我得到了以下错误 分段错误(核心转储) …

c linux openssl shared-libraries

2
推荐指数
1
解决办法
4916
查看次数

linux中的汇编代码产生了多少延迟

在装配中经历了这个链接延迟,以增加装配延迟.我想通过添加不同的延迟值来执行一些实验.

生成延迟的有用代码

; start delay

mov bp, 43690
mov si, 43690
delay2:
dec bp
nop
jnz delay2
dec si
cmp si,0    
jnz delay2
; end delay
Run Code Online (Sandbox Code Playgroud)

我从代码中理解的是,延迟与执行nop指令所花费的时间成比例(43690x43690).所以在不同系统和不同版本的操作系统中,延迟会有所不同.我对吗?

任何人都可以向我解释如何计算nsec的延迟量,下面的汇编代码正在生成,以便我可以结束我在实验设置中添加的延迟的实验?

这是我用来生成延迟而不理解使用43690值的逻辑的代码(我在原始源代码中只对一个循环使用了一个循环).为了产生不同的延迟(不知道它的值),我只改变了数字43690到403690或其他值.

32位操作系统中的代码

movl  $43690, %esi   ; ---> if I vary this 4003690 then delay value ??
.delay2:
    dec %esi
    nop
    jnz .delay2
Run Code Online (Sandbox Code Playgroud)

这个汇编代码会产生多少延迟?

如果我想在microsec中生成100nsec或1000nsec或任何其他延迟,那么我需要在寄存器中加载什么初始值?

我使用的是ubuntu 16.04(32位和64位),Intel(R)Core(TM)i5-7200U CPU @ 2.50GHz和Core-i3 CPU 3470 @ 3.20GHz处理器.

先感谢您.

linux x86 assembly intel delay

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

如何强制禁用 intel_pstate?即使在 grub 中使用 intel_pstate=disable 选项,重启时也会启用 intel_pstate

我正在尝试使用 cpu 频率缩放来设置 cpu 频率。在我的系统中,只支持 powersave 、 performance frequency-scaling-governor 。在其他文档中解释过,默认情况下,intel_pstate 是启用的,它只支持 powersave ,performance frequency-scaling-governor,解决方案是禁用 intel_pstate。所以我尝试禁用如下

sudo nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="intel_pstate=disable"
sudo update-grub
Run Code Online (Sandbox Code Playgroud)

重新启动时,启用 intel_pstate。

所以,我再次对 grub 进行了以下更改

sudo nano /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="intel_pstate=disable acpi=force"
sudo update-grub
Run Code Online (Sandbox Code Playgroud)

重新启动时,它仍然显示 intel_pstate 已启用。

当我执行以下命令时,

$ cpupower -c all frequency-info

    analyzing CPU 7:
      driver: intel_pstate
      CPUs which run at the same hardware frequency: 7
      CPUs which need to have their frequency coordinated by software: 7
      maximum transition latency:  Cannot determine or is not supported.
      hardware limits: 1.60 GHz …
Run Code Online (Sandbox Code Playgroud)

linux cpu intel cpu-architecture linux-kernel

0
推荐指数
1
解决办法
2万
查看次数