在C中进行类型转换后复制数组的更快方法?

时间:2013-06-20 11:47:58

标签: c arrays optimization

我有一个二维整数数组InArray[2][60],其中包含2个LS字节的short数据和2个MS字节的位字段数据。请建议一种更快的方法来提取short数据并将其复制到short OutArray[60],这些内容位于memcpy()的行上。我认为迭代每个项目并不是最佳的方法。 TIA

编辑:添加代码段

int InArray[2][60];
short OutArray[60];
for (int i=0; i < 60;i++)
{
    OutArray[i] = (short)(InArray[0][i] & 0xffff);
}

是否有更好的,可能更快的方法

2 个答案:

答案 0 :(得分:2)

如果你真的要复制一个60元素的数组,那就无所谓了。

如果阵列较大和/或你正在做很多次,那么你需要查看SIMD指令集:英特尔平台上的SSEx,PPC上的Altivec ...... / p>

例如,使用SSE4,您可以使用_mm_packus_epi32()将2 * 4个32位操作数打包(并饱和)到8个16位操作数中。

您的编译器可能有内在函数来使用它们:http://msdn.microsoft.com/en-us/library/hh977022.aspxhttp://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/PowerPC-AltiVec-Built_002din-Functions.html ...

答案 1 :(得分:1)

如果您多次这样做,这只会有所帮助。我使用Agner Fog的vectorclass来做到这一点(http://www.agner.org/optimize/vectorclass.zip)。这是一个使用SSE / AVX的类。但是,如果您在问题中添加标签SSE和AVX,您将找到最佳答案。

如果可以确保阵列是16字节或32字节对齐,那么您也会得到更好的结果。在下面的代码中,它也有助于使数组的宽度等于64(即使你只使用60个元素)或使数组的长度为64的倍数。

#include <stdio.h>
#include "vectorclass.h"

void foo(int InArray[2][60],  short OutArray[60]) {
    for (int i=0; i < 60; i++) {
        OutArray[i] = (short)(InArray[0][i] & 0xffff);
    }
}

void foo_vec8s(int InArray[2][60],  short OutArray[60]) {
    int i=0;
    for (; i <(60-8); i+=8) {
        Vec8s v1 = Vec8s().load(&InArray[0][i]);
        Vec8s v2 = Vec8s().load(&InArray[0][i+4]);
        Vec8s out = blend8s<0,2,4,6,8,10,12,14>(v1,v2);
        out.store(&OutArray[i]);
    }
    //clean up since arrays are not a multiple of 64
    for (;i < 60; i++) {
        OutArray[i] = (short)(InArray[0][i] & 0xffff);
    }
}

int main() {
    int InArray[2][60];
    for(int i=0; i<60; i++) { 
        InArray[0][i] = i | 0xffff0000;
    }

    short OutArray1[60] = {0};
    foo(InArray, OutArray1);
    for(int i=0; i<60; i++) {
        printf("%d ", OutArray1[i]);
    } printf("\n");

    short OutArray2[60] = {0};
    foo_vec8s(InArray, OutArray2);
    for(int i=0; i<60; i++) {
        printf("%d ", OutArray2[i]);
    } printf("\n");  
}