Используя инструкции SSE

Другой способ сделать это - поставить

cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' ); 

после того, как ваш cin>>number; полностью очистит входной буфер (отклонение всех дополнительных символов до тех пор, пока не будет найдена новая строка). Вы должны #include <limits> получить метод max().

28
задан Naveen 25 February 2009 в 15:55
поделиться

14 ответов

  1. инструкции SSE являются конкретным процессором. Можно искать который поддержки процессора который версия SSE на Википедию.
  2. , Если код SSE будет быстрее или не зависит от многих факторов: первое, конечно, является ли проблема ограниченной памятью или зависящей от ЦП. Если шина памяти будет узким местом, то SSE не поможет многому. Попытайтесь упростить свои целочисленные вычисления, если это делает код быстрее, это является, вероятно, зависящим от ЦП, и у Вас есть хороший шанс ускорения его.
  3. знать, что запись SIMD-кода намного более трудна, чем запись C ++-code, и что получающийся код намного более трудно изменить. Всегда совершенствуйте код C++, Вы захотите его как комментарий и проверять правильность Вашего ассемблерного кода.
  4. Думают о пользовании библиотекой как IPP, который реализует общие операции SIMD низкого уровня, оптимизированные для различных процессоров.
24
ответ дан Niki 14 October 2019 в 10:04
поделиться

Я не рекомендую делать это самостоятельно, если Вы не являетесь довольно опытными с блоком. Используя SSE, более, чем вероятный, потребует тщательной перестройки Ваших данных, как , Skizz указывает, и преимущество часто сомнительно в лучшем случае

для Вас, вероятно, было бы намного лучше записать очень маленькие циклы и сохранить Ваши данные очень плотно организованными и просто полагаться на компилятор, делающий это для Вас. И компилятор C Intel и GCC (начиная с 4.1) могут автовекторизовать Ваш код и вероятно сделают лучшее задание, чем Вы. (Просто добавьте - ftree-векторизуют к Вашему CXXFLAGS.)

Редактирование : Другая вещь, которую я должен упомянуть, состоит в том, что несколько компиляторов поддерживают блок intrinsics , который был бы, вероятно, IMO, быть легче использовать, чем asm () или __ asm {} синтаксис.

0
ответ дан Community 14 October 2019 в 10:04
поделиться

Взгляните на встроенный ассемблер для C/C++, вот статья DDJ. Если Вы не будете на 100% уверены, что Ваша программа будет работать на совместимой платформе, необходимо следовать рекомендациям, которые многие дали здесь.

1
ответ дан epatel 14 October 2019 в 10:04
поделиться

При использовании инструкций SSE Вы, очевидно, ограничены процессорами, которые поддерживают их. Это означает x86, относясь ко времени Pentium приблизительно 2 (не может помнить точно, когда они были представлены, но это давным-давно)

SSE2, который, насколько я могу вспомнить, является тем, который предлагает целочисленные операции, несколько более свежо (Pentium 3? Хотя первые процессоры AMD Athlon не поддерживали их)

В любом случае, у Вас есть две опции для использования этих инструкций. Любая запись весь блок кода в блоке (вероятно, плохая идея. Это делает фактически невозможным для компилятора оптимизировать Ваш код, и человеку очень трудно записать эффективный ассемблер).

, С другой стороны, используют intrinsics доступное с Вашим компилятором (если не изменяет память, они обычно определяются в xmmintrin.h)

, Но снова, производительность не может улучшиться. Код SSE излагает дополнительные требования данных, которые он обрабатывает. Главным образом тот для учета - то, что данные должны быть выровненные на 128-разрядных границах. Должны также быть немногие, или никакие зависимости между значениями, загруженными в тот же регистр (регистр SSE на 128 битов может содержать 4 ints. Добавление первого и второго вместе не оптимально. Но добавление всех четырех ints к соответствующим 4 ints в другом регистре будет быстро)

, может быть заманчиво пользоваться библиотекой, которая обертывает всю игру SSE низкого уровня, но это могло бы также разрушить любой потенциальный выигрыш в производительности.

я не знаю, как поддержка целочисленной операции хорошего SSE, так, чтобы мог также быть фактор, который может ограничить производительность. SSE главным образом предназначен для ускорения операций с плавающей точкой.

6
ответ дан jalf 14 October 2019 в 10:04
поделиться

Если Вы намереваетесь использовать Microsoft Visual C++, необходимо считать это:

http://www.codeproject.com/KB/recipes/sseintro.aspx

4
ответ дан Migol 14 October 2019 в 10:04
поделиться

Только для добавления кратко к тому, что было сказано прежде о различных версиях SSE, являющихся доступным на различных центральных процессорах: Это может быть проверено путем рассмотрения соответствующих значений параметра, возвращенных инструкцией CPUID (см., например, документация Intel для деталей).

1
ответ дан PhiS 14 October 2019 в 10:04
поделиться

Напишите код, который помогает компилятору понять то, что Вы делаете. GCC поймет и оптимизирует код SSE, такой как это:

typedef union Vector4f
{
        // Easy constructor, defaulted to black/0 vector
    Vector4f(float a = 0, float b = 0, float c = 0, float d = 1.0f):
        X(a), Y(b), Z(c), W(d) { }

        // Cast operator, for []
    inline operator float* ()
    { 
        return (float*)this;
    }

        // Const ast operator, for const []
    inline operator const float* () const
    { 
        return (const float*)this;
    }

    // ---------------------------------------- //

    inline Vector4f operator += (const Vector4f &v)
    {
        for(int i=0; i<4; ++i)
            (*this)[i] += v[i];

        return *this;
    }

    inline Vector4f operator += (float t)
    {
        for(int i=0; i<4; ++i)
            (*this)[i] += t;

        return *this;
    }

        // Vertex / Vector 
        // Lower case xyzw components
    struct {
        float x, y, z;
        float w;
    };

        // Upper case XYZW components
    struct {
        float X, Y, Z;
        float W;
    };
};

Просто не забывают иметь-msse-msse2 на Ваших параметрах сборки!

2
ответ дан LiraNuna 14 October 2019 в 10:04
поделиться

Хотя верно, что SSE специфичен для некоторых процессоров (SSE2 может быть относительно безопасным, SSE2 намного меньше по моему опыту), вы можете обнаружить CPU во время выполнения и динамически загружать код в зависимости от целевого CPU.

1
ответ дан David Cournapeau 14 October 2019 в 10:04
поделиться

SIMD, которого SSE является примером, позволяет Вам делать ту же операцию на нескольких блоках данных. Так, Вы не получите преимущества для использования SSE как прямая замена для целочисленных операций, Вы только получите преимущества, если можно сделать операции на нескольких элементах данных сразу. Это включает загрузку некоторых значений данных, которые непрерывны в памяти, делая необходимую обработку и затем продвижение в следующий набор значений в массиве.

проблемы:

1, Если путь выполнения кода является иждивенцем на обработанных данных, SIMD становится намного более твердым реализовать. Например:

a = array [index];
a &= mask;
a >>= shift;
if (a < somevalue)
{
  a += 2;
  array [index] = a;
}
++index;

не легко сделать как SIMD:

a1 = array [index] a2 = array [index+1] a3 = array [index+2] a4 = array [index+3]
a1 &= mask         a2 &= mask           a3 &= mask           a4 &= mask
a1 >>= shift       a2 >>= shift         a3 >>= shift         a4 >>= shift
if (a1<somevalue)  if (a2<somevalue)    if (a3<somevalue)    if (a4<somevalue)
  // help! can't conditionally perform this on each column, all columns must do the same thing
index += 4

2, Если данные не непрерывны, тогда загрузка данных в инструкции SIMD громоздкая

3, код является конкретным процессором. SSE находится только на IA32 (Intel/AMD), и не все CPU IA32 поддерживают SSE.

необходимо проанализировать алгоритм и данные, чтобы видеть, может ли это быть SSE'd, и это требует знания, как SSE работает. Существует много документации относительно веб-сайта Intel.

15
ответ дан Tim Cooper 14 October 2019 в 10:04
поделиться

Инструкции SSE были первоначально только на процессорах Intel, но недавно (так как Athlon?) AMD поддерживает их также, поэтому если Вы действительно кодируете против системы команд SSE, необходимо быть портативными к большей части x86 procs.

Однако это не может стоить Вашего времени для изучения кодирования SSE, если Вы не уже знакомы с ассемблером на x86 - более легкая опция могла бы состоять в том, чтобы проверить Ваши документы компилятора и видеть, существуют ли опции позволить компилятору автоматически генерировать код SSE для Вас. Некоторые компиляторы делают очень хорошо векторизующие циклы таким образом. (Вы, вероятно, не удивлены услышать, что компиляторы Intel делают хорошее задание этого:)

2
ответ дан Mike 14 October 2019 в 10:04
поделиться

Этот вид проблемы является идеальным примером того, где хороший низкоуровневый профилировщик важен. (Что-то как VTune) Это может дать Вам намного более информированную идею того, где Ваши горячие точки лежат.

Мое предположение, от того, что Вы описываете, - то, что Ваша горячая точка, вероятно, будет отказами предсказания ветвлений, следующими из минуты / макс. использования вычислений если/еще. Поэтому использование SIMD intrinsics должно позволить Вам использовать минимальные инструкции / макс. инструкции, однако, могло бы стоить просто попытаться использовать минуту без веток / макс. caluculation вместо этого. Это могло бы достигнуть большинства усилений с меньшим количеством боли.

Что-то вроде этого:

inline int 
minimum(int a, int b)
{
  int mask = (a - b) >> 31;
  return ((a & mask) | (b & ~mask));
}
10
ответ дан Endre 14 October 2019 в 10:04
поделиться

Мы реализовали некоторый код обработки изображений, подобный тому, что Вы описываете, но на массиве байтов В SSE. Ускорение по сравнению с кодом C значительно, в зависимости от точного алгоритма больше, чем фактор 4, даже относительно компилятора Intel. Однако, поскольку Вы уже упомянули, что у Вас есть следующие недостатки:

  • Мобильность. Код будет работать на каждом подобном Intel ЦП, так также AMD, но не на других центральных процессорах. Это не проблема для нас, потому что мы управляем целевыми аппаратными средствами. Переключение компиляторов и даже к ОС на 64 бита может также быть проблемой.

  • у Вас есть крутая кривая обучения, но я нашел, что после схватывания, принципы, пишущий новые алгоритмы не являются этим трудно.

  • Пригодность для обслуживания. Большая часть C или программисты на C++ не знают о блоке/SSE.

Мой совет Вам будет состоять в том, чтобы пойти для него, только если Вам действительно нужно повышение производительности, и Вы не можете найти функцию для своей проблемы в библиотеке как Intel IPP, и если можно жить с проблемами мобильности.

3
ответ дан Dani van der Meer 14 October 2019 в 10:04
поделиться

SIMD intrinsics (такой как SSE2) может ускорить этот вид вещи, но взять экспертные знания для использования правильно. Они очень чувствительны к выравниванию и конвейерно обрабатывают задержку; небрежное использование может сделать производительность еще хуже, чем это было бы без них. Вы заставите намного более легкое и больше непосредственного ускорения от простого использования упреждающей выборки кэша удостоверяться, что все Ваши ints находятся в L1 как раз к Вам для работы на них.

, Если для Вашей функции не нужна пропускная способность лучше, чем 100 000 000 целых чисел в секунду, SIMD, вероятно, не стоит проблемы Вам.

1
ответ дан Crashworks 14 October 2019 в 10:04
поделиться

Из своего опыта могу сказать, что SSE дает огромное (в 4 раза и выше) ускорение по сравнению с простой версией кода на Си (без встроенного asm, без использования intrinsics), но оптимизированный вручную ассемблер может победить ассемблер, сгенерированный компилятором, если компилятор не может понять, что задумал программист (поверьте мне, компиляторы не покрывают все возможные комбинации кода и никогда не покроют). И еще, компилятор не может каждый раз компоновать данные так, чтобы они выполнялись с максимально возможной скоростью. Но вам нужен большой опыт для увеличения скорости по сравнению с Intel-компилятором (если это возможно).

3
ответ дан 28 November 2019 в 02:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: