标签: cpu-cache

优化不同阵列的ARM缓存使用情况

我想在ARM Cortex A8处理器上移植一小段代码.L1缓存和L2缓存都非常有限.我的程序中有3个数组.其中两个是按顺序访问的(大小>阵列A:6MB,阵列B:3MB),第三个阵列(大小>阵列C:3MB)的访问模式是不可预测的.虽然计算不是很严格,但是访问阵列C时存在巨大的缓存未命中.我认为一种解决方案是为阵列C分配更多的缓存(L2)空间,而对于阵列A和B则分配更少.但我不能找到任何方法来实现这一目标.我经历了ARM的预加载引擎但找不到任何有用的东西.

arm cpu-cache

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

将进程固定到CPU核心还是SMP节点有助于减少缓存一致性流量?

可以使用sched_setaffinity()调用将进程固定到一组特定的CPU内核.手册页说:

   Restricting a process to run on a single CPU also avoids the
   performance cost caused by the cache invalidation that occurs when a process
   ceases to execute on one CPU and then recommences execution on a different
   CPU.
Run Code Online (Sandbox Code Playgroud)

这几乎是一个显而易见的事情(或不是?).对我来说不那么明显的是 -

将LWP固定到特定CPU或SMP节点会降低缓存一致性总线流量吗?例如,由于进程正在运行固定,因此其他CPU不应修改其专用内存,因此只有属于同一SMP节点的CPU应保持高速缓存一致性.

linux cpu performance cpu-architecture cpu-cache

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

C++如何强制预取数据缓存?(数组循环)

我有这样的循环

start = __rdtsc();
unsigned long long count = 0;
for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
        count += tab[i][j];
stop = __rdtsc();
time = (stop - start) * 1/3;
Run Code Online (Sandbox Code Playgroud)

需要检查预取数据如何影响效率.如何在计算之前强制从内存中预取一些值到缓存中?

c++ prefetch cpu-cache

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

如何确保一段代码永远不会离开CPU缓存(L3)?

最新的英特尔XEON处理器拥有30MB的L3内存,足以容纳薄型1管理程序.

我有兴趣了解如何在CPU中保留这样的Hypervisor,即防止被刷新到RAM,或者至少在发送到内存/磁盘之前加密数据.

假设我们使用裸机运行,我们可以使用DRTM(延迟启动)来引导它,例如我们从不受信任的内存/磁盘加载,但是如果我们可以解密()用于解密的秘密,我们只能加载真实的操作系统.操作系统,在设置了适当的规则以确保发送到RAM的任何内容都已加密后进行.

ps我知道T​​XT的ACEA又称ACRAM(认证代码执行区域又称认证代码RAM)据说有这样的保证(即它限制在CPU缓存中)所以我想知道是否可以在此周围做一些技巧.

pps这似乎超出了目前的研究范围,所以我实际上并不确定答案是否可行.

cpu hypervisor low-level trusted-computing cpu-cache

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

memcpy()的速度受malloc()的不同方式的影响很大

我写了一个测试速度的程序memcpy().但是,如何分配内存会极大地影响速度.

#include<stdlib.h>
#include<stdio.h>
#include<sys/time.h>

void main(int argc, char *argv[]){
    unsigned char * pbuff_1;
    unsigned char * pbuff_2;
    unsigned long iters = 1000*1000;

    int type = atoi(argv[1]);
    int buff_size = atoi(argv[2])*1024;

    if(type == 1){ 
        pbuff_1 = (void *)malloc(2*buff_size);
        pbuff_2 = pbuff_1+buff_size;
    }else{
        pbuff_1 = (void *)malloc(buff_size);
        pbuff_2 = (void *)malloc(buff_size);
    }   

    for(int i = 0; i < iters; ++i){
        memcpy(pbuff_2, pbuff_1, buff_size);
    }   

    if(type == 1){ 
        free(pbuff_1);
    }else{
        free(pbuff_1);
        free(pbuff_2);
    }   
}
Run Code Online (Sandbox Code Playgroud)

操作系统是linux-2.6.35,编译器是GCC-4.4.5,选项"-std = c99 -O3".

在我的计算机上的结果(memcpy …

malloc performance gcc memcpy cpu-cache

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

链接列表,数组和硬件内存缓存

虽然之前已经提出了关于链表和数组的问题,但答案大多归结为我们大多数人在某些时候可能已经学到的东西:

  • 列表擅长插入和删除
  • 数组很擅长随机访问

现在像Bjarne Stroustrup这样受人尊敬的人认为,数组实际上总是优于链表,因为它们更好地利用了现代硬件中实现的缓存架构.他还指出,阵列的性能优势随着它们的大小而增加.

虽然我基本上理解他的论点并同意他,但我想知道当数组的大小远大于缓存大小时,这是否仍然是正确的.我会说,性能真的很重要.

总结一下:在大多数情况下,数组仍然比列表表现更好,即使它们的大小比缓存大小大得多,并且大部分操作都是插入或删除吗?如果是,如何解释?

language-agnostic arrays performance linked-list cpu-cache

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

CPU Cache在C中使用链接列表的缺点

我想知道链接列表与C中的连续数组相比有什么优缺点.因此,我读了一篇关于链表的维基百科文章. https://en.wikipedia.org/wiki/Linked_list#Disadvantages

根据这篇文章,缺点如下:

  • 由于指针使用的存储空间,它们使用的内存多于数组.
  • 必须从头开始按顺序读取链接列表中的节点,因为链接列表本质上是顺序访问.
  • 在反向遍历方面,链表中出现了困难.例如,单个链表很难向后导航,而双链表更容易阅读,内存浪费在分配上.

  • 节点存储不明确,大大增加了访问列表中各个元素所需的时间,尤其是CPU缓存.

我理解前3分,但我最后一点很难:

节点存储不明确,大大增加了访问列表中各个元素所需的时间,尤其是CPU缓存.

关于CPU Cache的文章没有提到任何关于非连续内存阵列的内容.据我所知,CPU缓存仅缓存经常使用的地址,总共10 ^ -6缓存未命中.

因此,我不明白为什么CPU缓存在非连续内存阵列方面的效率会降低.

c optimization caching linked-list cpu-cache

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

Write-Combining Buffer位于何处?86

Write-Combine缓冲区是如何物理连接的?我已经看到了说明许多变体的方框图:

  • 在L1和内存控制器之间
  • 在CPU的存储缓冲区和内存控制器之间
  • 在CPU的AGU和/或存储单元之间

它是依赖于微架构的吗?

x86 intel cpu-architecture cpu-cache amd-processor

6
推荐指数
3
解决办法
1406
查看次数

Cachegrind:为什么这么多缓存未命中?

我目前正在学习Linux下的各种分析和性能实用程序,特别是valgrind/cachegrind.

我有以下玩具程序:

#include <iostream>
#include <vector>

int
main() {
    const unsigned int COUNT = 1000000;

    std::vector<double> v;

    for(int i=0;i<COUNT;i++) {
        v.push_back(i);
    }

    double counter = 0;
    for(int i=0;i<COUNT;i+=8) {
        counter += v[i+0];
        counter += v[i+1];
        counter += v[i+2];
        counter += v[i+3];
        counter += v[i+4];
        counter += v[i+5];
        counter += v[i+6];
        counter += v[i+7];
    }

    std::cout << counter << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

用这个程序编译g++ -O2 -g main.cpp并运行valgrind --tool=cachegrind ./a.out,然后cg_annotate cachegrind.out.31694 --auto=yes产生以下结果:

    --------------------------------------------------------------------------------
-- Auto-annotated source: /home/andrej/Data/projects/pokusy/dod.cpp
-------------------------------------------------------------------------------- …
Run Code Online (Sandbox Code Playgroud)

c++ performance profiling cpu-cache cachegrind

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

有没有现代/古老的CPU /微控制器,其中缓存的字节存储实际上比字存储慢?

一个普遍的说法是,缓存中的字节存储可能导致内部读 - 修改 - 写周期,或者与存储完整寄存器相比会损害吞吐量或延迟.

但我从未见过任何例子.没有x86 CPU是这样的,我认为所有高性能CPU也可以直接修改缓存行中的任何字节.一些微控制器或低端CPU是否有不同之处,如果它们有缓存的话?

(我不计算字可寻址的机器,或者字节可寻址但没有字节加载/存储指令的Alpha.我说的是ISA本身支持的最窄的存储指令.)

在我的研究中回答现代x86硬件可以不将单个字节存储到内存中吗?,我发现Alpha AXP省略字节存储的原因假设它们被实现为真正的字节存储到缓存中,而不是包含字的RMW更新.(因此,它会使L1d缓存的ECC保护更加昂贵,因为它需要字节粒度而不是32位).

所有现代架构(早期Alpha除外)都可以对不可缓存的内存(而不是RMW周期)进行真正的字节加载/存储,这对于为具有相邻字节I/O寄存器的设备编写设备驱动程序是必需的.(例如,使用外部启用/禁用信号来指定更宽总线的哪些部分保存实际数据,例如此ColdFire CPU /微控制器上的2位TSIZ(传输大小),或者像PCI/PCIe单字节传输,或者像DDR一样SDRAM控制信号掩盖选定的字节.)

对于微控制器设计,可能需要在缓存中为字节存储执行RMW循环,即使它不是针对像Alpha这样的SMP服务器/工作站的高端超标量流水线设计?

我认为这种说法可能来自可以用字寻址的机器.或者来自未对齐的32位存储,需要在许多CPU上进行多次访问,并且人们错误地将其从一般存储到字节存储.


为了清楚起见,我希望到同一地址的字节存储循环将在每次迭代中以与字存储循环相同的周期运行.因此,对于填充阵列,32位存储可以比8位存储快4倍.(也许如果少了32位门店饱和的内存带宽,但8位店家没有.)但是,除非字节存储有一个额外的惩罚,你不会得到超过4倍的速度差.(或者无论宽度是多少).

而我在谈论asm.一个好的编译器会自动向量化C中的字节或int存储循环,并使用更宽的存储或目标ISA上的最佳存储.

; x86-64 NASM syntax
mov   rdi, rsp
; RDI holds at a 32-bit aligned address
mov   ecx, 1000000000
.loop:                      ; do {
    mov   byte [rdi], al
    mov   byte [rdi+2], dl     ; store two bytes in the same dword
      ; no pointer increment, this is the same 32-bit dword every time
    dec   ecx
    jnz …
Run Code Online (Sandbox Code Playgroud)

performance x86 arm cpu-architecture cpu-cache

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