用C ++实现SIMD

时间:2010-04-29 16:53:11

标签: c++ simd sse2

我正在研究一些代码,我正在尝试尽可能地优化它,基本上让它在一定的时间限制内运行。

以下是致电......

static affinity_partitioner ap;
parallel_for(blocked_range<size_t>(0, T), LoopBody(score), ap);

......以下是执行的内容。

void operator()(const blocked_range<size_t> &r) const {

    int temp;
    int i;
    int j;
    size_t k;
    size_t begin = r.begin();
    size_t end = r.end();

    for(k = begin; k != end; ++k) { // for each trainee
        temp = 0;
        for(i = 0; i < N; ++i) { // for each sample
            int trr = trRating[k][i];
            int ei = E[i];              
            for(j = 0; j < ei; ++j) { // for each expert
                temp += delta(i, trr, exRating[j][i]);
            }
        }           
        myscore[k] = temp;
    }
}

我正在使用英特尔的TBB来优化它。但我也一直在阅读关于SIMD和SSE2以及这种性质的事情。所以我的问题是,如何将变量(i,j,k)存储在寄存器中,以便CPU可以更快地访问它们?我认为答案与实施SSE2或其中的一些变体有关,但我不知道如何做到这一点。有什么想法吗?

编辑:这将在Linux机器上运行,但我相信使用英特尔的编译器。如果它有帮助,我必须在执行任何操作之前运行以下命令以确保编译器正常工作... source /opt/intel/Compiler/11.1/064/bin/intel64/iccvars_intel64.csh;源/opt/intel/tbb/2.2/bin/intel64/tbbvars.csh ...然后编译我做:icc -ltbb test.cxx -o test

如果没有简单的方法来实施SSE2,有关如何进一步优化代码的任何建议吗?

谢谢, 赫里斯托斯

4 个答案:

答案 0 :(得分:1)

如果要在C ++模块中使用汇编语言,可以将其放在asm块中,并继续使用块外部的变量名。您在asm块中使用的汇编指令将指定正在操作哪个寄存器等,但它们会因平台而异。

答案 1 :(得分:1)

你的问题代表了对正在发生的事情的一些困惑。 i,j,k变量几乎肯定已经存在于寄存器中,假设您正在进行优化编译(您应该这样做 - 在您的icc调用中添加“-O2”)。

您可以使用asm块,但考虑到您已经在使用ICC,更简单的方法是使用SSE内在函数。英特尔的文档就在这里 - http://www.intel.com/software/products/compilers/clin/docs/ug_cpp/comm1019.htm

看起来您可以SIMD-ize顶级循环,但它将在很大程度上取决于您的delta函数。

答案 2 :(得分:0)

如果您正在使用GCC,请参阅http://gcc.gnu.org/projects/tree-ssa/vectorization.html了解如何帮助编译器自动矢量化您的代码,以及示例。

否则,您需要告诉我们您正在使用的平台。

答案 3 :(得分:0)

编译器应该为您执行此操作。例如,在VC ++中,您只需打开SSE2。