В моей компании я работаю над предоставлением более быстрого SSE-пути для некоторого горячего кода. Я использую встроенный подход, который держится на C++ и действительно показывает впечатляющие результаты.Как я могу принять решение на основе типа внутри макроса?
Весь код должен работать только на float
и double
, поэтому я создал шаблонный класс операций SSE, который я специализировал для обоих. То, что я действительно не нравится то, что эти два класса выглядят почти идентично для типа номера (float
/double
), используемый тип SSE (__m128
/__m128d
) и intrisics суффиксом (_ps
/_pd
), за исключением примерно так:
template<>
struct SseOperations<float> : public Sse<float>
{
typedef __m128 vector;
vector load(float const * const from) const
{
return _mm_loadu_ps(from);
}
vector add(vector const & a, vector const & b) const
{
return _mm_add_ps(a, b);
}
// etc.
};
и
template<>
struct SseOperations<double> : public Sse<double>
{
typedef __m128d vector;
vector load(double const * const from) const
{
return _mm_loadu_pd(from);
}
vector add(vector const & a, vector const & b) const
{
return _mm_add_pd(a, b);
}
// etc.
};
Я не знаю, как объединить это с помощью шаблона магии, из-за суффикса различных Intrinsics.
Тогда мне пришла в голову возможность макросов, которая одолжила бы для этой цели. Таким образом, мне удалось поставить полный специализированный класс в макрос, который я мог бы использовать для создания обоих классов с:
SSE_OPERATIONS(float, __m128, _ps);
SSE_OPERATIONS(double, __m128d, _pd);
Я знаю, что макросы зло и все, но, по крайней мере, в этом случае я не вижу какой-либо из типичные опасности, и он выполняет свою работу.
Что меня беспокоит, так это то, что второй и третий макропараметры являются избыточными; их можно было бы вывести из первого, только я понятия не имею, как это сделать. #if
и его друзья не должны работать, потому что sizeof()
не работает во время предварительной обработки.
Поиск решений неожиданно затруднен из-за #if
тем, сильно загрязняющих результаты. Может ли кто-нибудь сказать мне, как сделать решение на уровне макросов для этой проблемы?
PS: Я слышал о Boost Preprocessor, но мне не разрешено использовать его.
Обновление: Хотя я прошу решение для макросов, я бы тоже принял хорошее решение для шаблонов. Для этого знайте, что я инкапсулирую как минимум 7 встроенных функций - на всякий случай, если бы раздувал код шаблона.
Если вы можете сделать это с помощью макроса, вы можете сделать это без макроса. –
Я не вижу, как макро параметры являются избыточными. Эти 3 имени полностью не связаны на уровне маркера.Ваш макрос должен по необходимости указывать логическую связь между этими тремя токами. Вы просто не можете вывести '_ps' из' float'. Конечно, это в конечном итоге вызвано крайне ограниченной интеграцией SSE-примитивов и C++. Если бы ответственный разработчик компилятора понял и то, и другое, он бы понял, что 'operator +' является совершенно нормальным именем для '_mm_add_pd'. Перегрузка оператора составляет несколько десятков лет; не нужно продолжать вводить ограничения ассемблера на программы сегодня. – MSalters
Хорошо, они не избыточны для ПП, но для меня. Если бы у меня был макрос, если бы я мог просто вычислить/установить их в начале макроса, заданного только 'float' или' double'. – primfaktor