У меня есть структура, которая представляет вектор. Этот вектор состоит из двух однобайтовых целых чисел. Я использую их для сохранения значений от 0 до 255.
typedef uint8_T unsigned char;
struct Vector
{
uint8_T x;
uint8_T y;
};
Теперь основной вариант использования в моей программе — умножить оба элемента вектора на 32-битное значение с плавающей запятой:
typedef real32_T float;
Vector Vector::operator * ( const real32_T f ) const {
return Vector( (uint8_T)(x * f), (uint8_T)(y * f) );
};
Это нужно делать очень часто. Есть ли способ, что эти два умножения могут быть выполнены одновременно? Может быть, путем векторизации, SSE или подобным? Или компилятор Visual studio уже делает это одновременно?
Другой вариант использования — это интерполяция между двумя векторами.
Vector Vector::interpolate(const Vector& rhs, real32_T z) const
{
return Vector(
(uint8_T)(x + z * (rhs.x - x)),
(uint8_T)(y + z * (rhs.y - y))
);
}
Это уже использует оптимизированный подход интерполяции (https://stackoverflow.com/a/4353537/871495).
Но снова значения векторов умножаются на то же скалярное значение.
Есть ли возможность повысить производительность этих операций?
Спасибо
(Я использую Visual Studio 2010 с 64-битным компилятором)
По моему опыту, Visual Studio (особенно старая версия, такая как VS2010) сама по себе не делает много векторизации. Они улучшили его в более новых версиях, поэтому, если вы можете, вы можете увидеть, ускоряет ли ваш код изменение компилятора.
В зависимости от кода, который использует эти функции, и оптимизации, которую выполняет компилятор, может даже не быть вычислений, которые замедляют вашу программу. Вызовы функций и ошибки кэширования могут повредить гораздо больше.
Вы можете попробовать следующее:
float
в uint8_t
(например, если ваши поплавки находятся в диапазоне [0,1]), попробуйте использовать float
везде. Это может позволить компилятору делать гораздо лучшую оптимизацию.Вы не показали полный алгоритм, но преобразования между целыми числами и числами с плавающей запятой — очень медленная операция. Исключение этой операции и использование только одного типа (если возможно, предпочтительно целых чисел) может значительно улучшить производительность.
Альтернативно, вы можете использовать lrint()
сделать преобразование как объяснено Вот.