реализовать SIMD в C ++ - PullRequest
       18

реализовать SIMD в C ++

0 голосов
/ 29 апреля 2010

Я работаю над небольшим количеством кода и пытаюсь максимально оптимизировать его, в основном, чтобы он работал в течение определенного периода времени.

Следующее делает звонок ...

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 Intel для оптимизации этого. Но я также читал о SIMD и SSE2 и тому подобном. Итак, мой вопрос: как мне хранить переменные (i, j, k) в регистрах, чтобы процессор мог быстрее к ним обращаться? Я думаю, что ответ связан с реализацией SSE2 или его вариации, но я понятия не имею, как это сделать. Есть идеи?

Редактировать: Это будет работать на Linux-машине, но я думаю, что с помощью компилятора Intel. Если это помогает, мне нужно выполнить следующие команды, прежде чем что-либо делать, чтобы убедиться, что компилятор работает ... 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 ]

1 голос
/ 29 апреля 2010

Если вы хотите использовать ассемблер в модуле C ++, вы можете просто поместить его в блок asm и продолжать использовать имена переменных вне блока. Инструкции по сборке, которые вы используете в блоке asm, будут указывать, какой регистр и т. Д. Используется, но они будут различаться в зависимости от платформы.

1 голос
/ 29 апреля 2010

Ваш вопрос представляет некоторую путаницу в том, что происходит. Переменные i, j, k почти наверняка уже содержатся в регистрах, при условии, что вы компилируете с оптимизацией (что вы должны сделать - добавьте «-O2» в ваш вызов icc).

Вы можете использовать блок asm, но более простой способ, учитывая, что вы уже используете ICC, - это использование встроенных функций SSE. Документация Intel для них здесь - http://www.intel.com/software/products/compilers/clin/docs/ug_cpp/comm1019.htm

Похоже, вы можете SIMD-ize петли верхнего уровня, хотя это будет сильно зависеть от того, что ваша функция delta.

0 голосов
/ 29 апреля 2010

Компилятор должен сделать это для вас.Например, в VC ++ вы можете просто включить SSE2.

0 голосов
/ 29 апреля 2010

Если вы используете GCC, см. http://gcc.gnu.org/projects/tree-ssa/vectorization.html, чтобы помочь компилятору автоматически векторизовать ваш код, и примеры.

В противном случае вам необходимо сообщить нам, какую платформу вы используете.

...