У меня есть функция, которая считает пересечения со сферой template<class _Ty,

size_t _Size>
static inline vector_impl<_Ty, 2ull> ray_sphere_intersect(const vector_impl<_Ty, _Size>& r0, const vector_impl<_Ty, _Size>& rd, const vector_impl<_Ty, _Size>& s0, const _Ty sr)
{
vector_impl<_Ty, 2ull> res{};
_Ty a = length2(rd);
vector_impl<_Ty, _Size> s0_r0 = r0 - s0;
_Ty b = static_cast<_Ty>(2) * dot(rd, s0_r0);
_Ty c = length2(s0_r0) - (sr * sr);
if (b * b - static_cast<_Ty>(4) * a * c < static_cast<_Ty>(0))
{
res[0] = res[1] = -1.f;
return res;
}

res[0] = (-b - sqrt((b * b) - static_cast<_Ty>(4) * a * c)) / (static_cast<_Ty>(2) * a);
res[1] = (-b + sqrt((b * b) - static_cast<_Ty>(4) * a * c)) / (static_cast<_Ty>(2) * a);
return res;
}

И есть её такая же на sse2
inline __m128 _dot_product_sse2(const __m128& _lhs, const __m128& _rhs)
{
auto t0 = _mm_mul_ps(_lhs, _rhs);

auto t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 3, 0, 1));
t0 = _mm_add_ps(t0, t1);
t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0, 1, 2, 3));
return _mm_add_ps(t0, t1);
}

inline void _sphere_intersect_vec128(const float(&_r0)[3ull], const float(&_rd)[3ull], const float(&_s0)[3ull], const float _sr, float(&_res)[2ull])
{
using namespace sse;

__m128 vr0 = _load_fvec128(_r0);
__m128 vrd = _load_fvec128(_rd);
__m128 vs0 = _load_fvec128(_s0);

float a = _mm_cvtss_f32(_dot_product_sse2(vrd, vrd));
__m128 vs0_r0 = _mm_sub_ps(vr0, vs0);

float b = 2.f * _mm_cvtss_f32(_dot_product_sse2(vrd, vs0_r0));
float c = _mm_cvtss_f32(_dot_product_sse2(vs0_r0, vs0_r0)) - (_sr * _sr);

float discriminant = (b * b) - (4.f * a * c);

// Check discriminant is greather then zero
if (discriminant < 0.f)
{
_res[0] = _res[1] = -1.f;
return;
}

discriminant = sqrtf(discriminant);
float a2 = 2.f * a;

_res[0] = (-b - discriminant) / a2;
_res[1] = (-b + discriminant) / a2;
}

Компилирую msvc 2019, оптимизация O2. И у меня выходит, что код без использования sse2 быстрее в 10 раз. Подскажите почему такое может быть? Данные выровнены по 16 байт

9 ответов

15 просмотров

Там ещё вопрос к тому, как ты замеряешь.

adamfull- Автор вопроса
Dark Embrace
Там ещё вопрос к тому, как ты замеряешь.

chrono::high_resolution_clock и 100000000 семплов

adamfull
chrono::high_resolution_clock и 100000000 семплов

Возьми https://github.com/google/benchmark

adamfull- Автор вопроса
Dark Embrace
Возьми https://github.com/google/benchmark

Спасибо, завтра уже гляну

Ты похоже просто два скалярных произведения vec3 в симд положил и ждешь прироста. То есть вместо 5 операций, у тебя стало 2 раза переложить в память, потом 1 раз перемножить вектора, вынуть и сложить 3 раза. Все верно?

adamfull- Автор вопроса
Павел Munrocket
Ты похоже просто два скалярных произведения vec3 в...

Не совсем понял по поводу того что два положил

adamfull- Автор вопроса
Павел Munrocket
Ты похоже просто два скалярных произведения vec3 в...

1 раз положил, 1 раз перемножил, 8 раз сложил и два раза зашафлил. Скорее так

Смотри бинарь

У тебя a=1 всегда, его можно не считать. Так же коэффициенты 2 и 4 можно сократить в неравенстве, тоже не нужны в расчете. Скорее всего тормозит шафл, как будто быстрее скалярно поэлементно сложить. А так же возможно компилятор не смог переставить порядок вычислений и ему нужно явно поставить инструкции для 2-х скалярных умножений рядом: __m256 заюзать для двух векторных умножений, 64 битный проц же.

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

Обсуждают сегодня

что насчет пагинга? на осдеве непонятно(
Vi Chapmann 🪙
26
Продолжая диалог про свифт в проде – сейчас возник вопрос в активном наборе бекендеров. В основном в нашей компании мы фанаты Java Spring и полностью ей довольны. Однако найм ...
Guseyn
27
Читаю сейчас [нет, уже больше не читаю!] курсовую о Булгакове, написанную, похоже, с помощью ChatGPT. Это удивительный психоделический опыт. Текст в основном написан в стиле б...
✨ Uni [🌊 В отпуске]
1
если загрузчик efi? если сама PML4 PDPT PDT PT лежит в неудобном для меня месте?
Vi Chapmann 🪙
8
Всем привет! поделитесь, пож-та, как кто дебажил / решал проблему с 504 Time out ошибкой от nginx, когда стучишься на свой vapor сервер? в логах /var/log/nginx/error.log е...
Paul
24
А я же правильно понимаю, что инструкция AT в ld только сохраняет метаинформации о том, куда загрузить сегмент, которую далее из эльфика читает grub(ну если граб)? Но я тогда ...
Evg Resh
2
Господа, импользую кастомный загрузчик, ядро запускается сразу в длинном режиме, хочу узнать, сколько всего физической ОЗУ есть у машины. И, может, знаете какие-то подводные к...
Vi Chapmann 🪙
6
а причем тут линкер скрипты? UEFI где-то расположила PML4 и прочее, а мне надо переложить её в другое физическое место. как?
Vi Chapmann 🪙
6
Это фейк @cruppto_newbot?
Antskup
13
неужели нету аппаратного метода узнать объём ОЗУ?
Vi Chapmann 🪙
6
Карта сайта