Performance 如何在C+中保存矩阵+;以非线性方式

Performance 如何在C+中保存矩阵+;以非线性方式,performance,caching,matrix,optimization,memory-access,Performance,Caching,Matrix,Optimization,Memory Access,我必须为Levenshtein距离问题编程一个优化的多线程实现。它可以用矩阵的动态规划来计算,覆盖得足够好了 现在,我可以同时计算对角线元素。没关系 我现在的问题是缓存。C++中的矩阵是常量,一行一行地保存在内存中,对吗?这对我来说不太好,因为我需要前一行的2个元素和当前行的1个元素来计算我的结果,这是可怕的缓存方式。缓存将保存当前行(或其中的一部分),然后我请求保存前一行,它可能不再保存前一行。 然后对于另一个,我需要对角线的不同部分,所以再次,我要求完全不同的行,缓存将不会为我准备好这些行

我必须为Levenshtein距离问题编程一个优化的多线程实现。它可以用矩阵的动态规划来计算,覆盖得足够好了

现在,我可以同时计算对角线元素。没关系


我现在的问题是缓存。C++中的矩阵是常量,一行一行地保存在内存中,对吗?这对我来说不太好,因为我需要前一行的2个元素和当前行的1个元素来计算我的结果,这是可怕的缓存方式。缓存将保存当前行(或其中的一部分),然后我请求保存前一行,它可能不再保存前一行。 然后对于另一个,我需要对角线的不同部分,所以再次,我要求完全不同的行,缓存将不会为我准备好这些行

因此,我想将矩阵以块或diagoals的形式保存到内存中。这将减少cachce失误,并使我的实现再次加快

你是怎么做到的?我试着在互联网上搜索,但我永远也找不到任何能给我指路的东西。是否可以告诉C++如何在内存中排序该类型?
编辑:你们中的一些人似乎对我问题的性质感到困惑。我想以一种定制的方式将矩阵(无论我是否将其设置为2D数组或任何其他方式)保存到内存中。通常情况下,2D数组将保存一行接一行,我需要使用对角线,因此缓存将丢失大量我将处理的大型矩阵(可能有数百万行和列)

我不是绝对确定,但我认为矩阵是以长数组的形式存储的,一行接一行,并通过指针算法映射到矩阵,因此您总是引用相同的地址并计算内存中值所在的距离


否则,您可以将其轻松实现为这种类型,并为您的矩阵实现运算符[int,int]

我不是绝对确定,但我认为矩阵是以长数组的形式一行接一行存储的,并使用指针算法映射到矩阵,因此,您总是引用相同的地址,并计算内存中值所在的距离


否则,您可以将其轻松实现为这种类型,并为矩阵实现运算符[int,int]

我相信您可能对(CPU)缓存有错误的认识

CPU缓存确实是线性的——也就是说,如果访问内存中的地址,它会将一些先前的和一些后续的内存位置带入缓存——这就像“猜测”后续访问将涉及一维闭合元素一样。然而,这在微观层面上是正确的。CPU的缓存由大量的小“行”(在最近的英特尔CPU中,所有缓存级别上都有64字节)组成。位置仅限于线路;不同的缓存线可以来自内存中完全不同的位置

因此,如果矩阵“需要前一行的两个元素和当前行的一个元素”,那么缓存应该可以很好地为您工作:一些缓存将保存前一行的元素,一些缓存将保存当前行的元素。当您前进到下一个元素时,整个缓存通常包含您需要访问的矩阵元素。只要确保您的迭代顺序与缓存线中的前进顺序一致即可

此外,在某些情况下,由于从主内存到缓存的映射,您可能会遇到不同线程对相同缓存线进行抖动的情况。在不深入细节的情况下,这是您需要考虑的问题(但同样,这与2D和1D数据无关)


编辑:正如geza所指出的,如果矩阵的行很长,您仍将使用简单的方法读取每个内存位置两次:一次作为当前行,然后再次作为前一行,因为每个值在用作前一行值之前将从缓存中逐出。如果要避免这种情况,可以迭代矩阵的分片,其大小(长度x宽度x大小of(元素))适合一级缓存(以及其他需要的内容)。您也可以考虑将数据存储在瓦片中,但我认为这不会太有用。

< P>我相信您可能对CPU缓存有错误的认识。p> CPU缓存确实是线性的——也就是说,如果访问内存中的地址,它会将一些先前的和一些后续的内存位置带入缓存——这就像“猜测”后续访问将涉及一维闭合元素一样。然而,这在微观层面上是正确的。CPU的缓存由大量的小“行”(在最近的英特尔CPU中,所有缓存级别上都有64字节)组成。位置仅限于线路;不同的缓存线可以来自内存中完全不同的位置

因此,如果矩阵“需要前一行的两个元素和当前行的一个元素”,那么缓存应该可以很好地为您工作:一些缓存将保存前一行的元素,一些缓存将保存当前行的元素。当您前进到下一个元素时,整个缓存通常包含您需要访问的矩阵元素。只要确保您的迭代顺序与缓存线中的前进顺序一致即可

此外,在某些情况下,由于从主内存到缓存的映射,您可能会遇到不同线程对相同缓存线进行抖动的情况。在不深入细节的情况下,这是您需要考虑的问题(但同样,这与2D和1D数据无关)

编辑:正如geza所指出的,如果矩阵的行很长,您仍将使用简单的方法读取每个内存位置两次:一次作为当前行,然后再次作为前一行,因为每个值在使用前都将从缓存中逐出