gpt4 book ai didi

C++ 池分配器与静态分配、缓存性能

转载 作者:行者123 更新时间:2023-11-30 04:05:33 25 4
gpt4 key购买 nike

鉴于我有两个并行且大小相同的以下结构数组:

    struct Matrix
{
float data[16];
};

struct Vec4
{
float data[4];
}

//Matrix arrM[256]; //for illustration
//Vec4 arrV[256];

假设我希望尽可能快地依次遍历两个数组。可以说函数是这样的:

for (int i=0; i < 256; ++i)
{
readonlyfunc(arrMPtr[i].data);
readonlyfunc(arrVPtr[i].data
}

假设我的分配是针对每个数组对齐的,无论是在静态分配还是堆内存的情况下。假设我的缓存行大小为 64 字节。

如果我将数据存储为,我能否实现相同的缓存位置和性能:

一个)

//aligned
static Matrix arrM[256];
static Vec4 arrV[256];

Matrix* arrMPtr = arrM[0];
Vec4* arrVPtr = arrV[0];

对比

B)

//aligned
char* ptr = (char*) malloc(256*sizeof(Matrix)+256*sizeof(Vec4));

Matrix* arrMPtr = (Matrix*) ptr;
Vec4* arrVPtr = (Vec4*) ptr+256*sizeof(Matrix);

最佳答案

内存的分配方式(堆分配或静态分配)对内存的缓存能力没有影响。由于这两种数据结构都相当大(分别为 1024 和 4096 字节),因此第一个和最后一个元素的精确对齐可能也不重要(但如果您使用 SSE 指令访问内容,它确实很重要!) .

内存是否靠近不会产生巨大差异,只要分配足够小以轻松放入缓存,但又大到足以占用多个缓存行。

如果您按顺序处理两个数组,您可能会发现使用具有 20 个浮点值的结构效果更好。但这只有在您不需要对数据做其他事情时才有效,而使用单个数组更有意义。

编译器翻译代码以避免额外内存访问的能力可能有所不同。这显然取决于实际代码(例如,编译器是否内联包含 for 循环的函数,它是否内联 readonlyfunc 代码等。如果是这样,静态分配可以从指针变体(加载指针的地址以获取数据的地址)转换为常量地址计算。在像这样的大循环中它可能不会产生巨大差异。

总是,当涉及到性能时,有时小事情会产生很大的不同,所以如果这真的很重要,请使用您的编译器和您的实际代码进行一些实验。我们只能根据我们的经验给出相对推测的建议。不同的编译器用相同的代码做不同的事情,不同的处理器用相同的机器代码做不同的事情(两种不同的实际架构(无论是指令集架构 ARM vs X86,还是架构的实现,例如 AMD Opteron vs Intel Atom 或 ARM Cortex A15 vs Cortex M3)。您特定系统上的内存配置也会影响事物,缓存有多大等等。

关于C++ 池分配器与静态分配、缓存性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23255823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com