优化数组转置功能

Gle*_*shi 8 c optimization caching loops matrix

我正在完成一项家庭作业,而且我的解决方案已经被困了几个小时.我们给出的问题是优化以下代码,以便它运行得更快,无论它变得多么混乱.我们应该使用诸如利用缓存块和循环展开之类的东西.

问题:

//transpose a dim x dim matrix into dist by swapping all i,j with j,i
void transpose(int *dst, int *src, int dim) {
    int i, j;

    for(i = 0; i < dim; i++) {
        for(j = 0; j < dim; j++) {
                dst[j*dim + i] = src[i*dim + j];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我所拥有的:

//attempt 1
void transpose(int *dst, int *src, int dim) {
    int i, j, id, jd;

    id = 0;
    for(i = 0; i < dim; i++, id+=dim) {
        jd = 0;
        for(j = 0; j < dim; j++, jd+=dim) {
                dst[jd + i] = src[id + j];
        }
    }
}

//attempt 2
void transpose(int *dst, int *src, int dim) {
    int i, j, id;
    int *pd, *ps;
    id = 0;
    for(i = 0; i < dim; i++, id+=dim) {
        pd = dst + i;
        ps = src + id;
        for(j = 0; j < dim; j++) {
                *pd = *ps++;
                pd += dim;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一些想法,如果我错了,请纠正我:

我已经考虑过循环展开但我不认为这会有所帮助,因为我们不知道NxN矩阵是否具有素数尺寸.如果我检查了它,它将包括过多的计算,这只会减慢功能.

缓存块不是很有用,因为无论如何,我们将线性访问一个数组(1,2,3,4),而另一个我们将在N的跳转中访问.虽然我们可以使函数滥用缓存并更快地访问src块,它仍然需要很长时间才能将它们放入dst矩阵中.

我也尝试过使用指针代替数组访问器,但我认为实际上并没有以任何方式加速程序.

任何帮助将不胜感激.

谢谢

jan*_*neb 7

缓存阻塞可能很有用.举个例子,假设我们的缓存行大小为64字节(这是x86目前使用的).因此,对于足够大的矩阵,使其大于缓存大小,那么如果我们转置16x16块(因为sizeof(int)== 4,因此16个整数适合缓存行,假设矩阵在缓存行边界上对齐) )我们需要从内存中加载32(来自源矩阵的16个,来自目标矩阵的16个)来自内存的缓存行并存储另外16行(即使存储不是连续的).相反,如果没有高速缓存阻塞转置等效的16*16元素,则需要我们从源矩阵加载16个高速缓存行,但是16*16 = 256个高速缓存行要加载然后存储用于目标矩阵.