Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic features: Vec8f and Vec4f #1

Merged
merged 67 commits into from
Jan 7, 2024
Merged

Basic features: Vec8f and Vec4f #1

merged 67 commits into from
Jan 7, 2024

Conversation

NamorNiradnug
Copy link
Owner

@NamorNiradnug NamorNiradnug commented Jan 3, 2024

Closes #12

@NamorNiradnug
Copy link
Owner Author

CI problem: rust compiler won't tell about missing intrinsics on no-AVX build. Instead it fails to inline those but then successfully links them, resulting AVX instructions working.

src/vec4f.rs Outdated Show resolved Hide resolved
src/vec4f.rs Outdated Show resolved Hide resolved
src/vec4f.rs Outdated Show resolved Hide resolved
src/vec4f.rs Outdated Show resolved Hide resolved
src/vec4f.rs Outdated
#[inline(always)]
fn from(value: Vec4f) -> Self {
let mut result = MaybeUninit::<Self>::uninit();
unsafe {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Когда напишем реализацию без sse, надо будет этот кусок проверить под miri

Copy link
Owner Author

@NamorNiradnug NamorNiradnug Jan 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я зачем без sse? Я прогнал под miri, оно не наругалось. Зато нашел другую багу (as_ptr вместо as_mut_ptr). Надо в CI тоже добавить запуск под miri, но с ним есть проблемы:

  • оно как-то странно работает с .cargo/config.toml (но это ладно) cargo clean помог
  • оно пока не умеет AVX, но есть готовый PR
    • наверное из-за этого compile_fail-тесты для extract_const компилируются при запуском под miri

src/vec8f.rs Outdated

use crate::{common::SIMDVector, macros::vec_overload_operator, Vec4f};

#[cfg(avx)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У тебя в этом файле ооочень много таких проверок на cfg(avx)
Может лучше так:

// vec8f.rs
#[cfg(avx)]
mod vec8f_avx;
#[cfg(avx)]
pub use vec8f_avx::*;

#[cfg(not(avx))]
mod vec8f_noavx;
#[cfg(not(avx))]
pub use vec8f_noavx::*;

И писать реализацию уже в vec8f_avx.rs и vec8f_noavx.rs
Обсуждаемо, но нужны аргументы почему лучше все в одном файле

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И да, зачем no_avx если есть cfg(not(avx))?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут потому что мне лень писать :)

Copy link
Owner Author

@NamorNiradnug NamorNiradnug Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У тебя в этом файле ооочень много таких проверок на cfg(avx)
Может лучше так:

// vec8f.rs
#[cfg(avx)]
mod vec8f_avx;
#[cfg(avx)]
pub use vec8f_avx::*;

#[cfg(not(avx))]
mod vec8f_noavx;
#[cfg(not(avx))]
pub use vec8f_noavx::*;

И писать реализацию уже в vec8f_avx.rs и vec8f_noavx.rs
Обсуждаемо, но нужны аргументы почему лучше все в одном файле

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

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А в оригинале все рядом лежит у Fog-а?

Copy link
Owner Author

@NamorNiradnug NamorNiradnug Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А в оригинале все рядом лежит у Fog-а?

У него реализация без AVX отдельно, а оптимизации рядом.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно сделать так, что документация всегда идет из не-avx модуля через cfg(all(avx, not(doc))), а avx - просто реализации. Тогда надо будет аккуратно следить, что интерфейс один и тот же, но по идее тесты это решат.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Другой вариант, который мне пока нравится больше всего, но потребует больше всего кода:
Сделать три файла:

  1. vec4f.rs
  2. vec4f_fallback.rs
  3. vec4f_avx.rs
    В Vec4f.rs сделать такое:
#[cfg(avx)]
mod impl;
#[cfg(not(avx))]
mod impl;

#[repr(transparent)]
struct Vec4f(impl::Vec4f);

impl Vec4f {
    // и тут doc
    pub fn extract(&self, index: usize) -> f32 {
        self.0.extract
    }
}

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Другой вариант, который мне пока нравится больше всего, но потребует больше всего кода: Сделать три файла:

1. `vec4f.rs`

2. `vec4f_fallback.rs`

3. `vec4f_avx.rs`
   В `Vec4f.rs` сделать такое:
#[cfg(avx)]
mod impl;
#[cfg(not(avx))]
mod impl;

#[repr(transparent)]
struct Vec4f(impl::Vec4f);

impl Vec4f {
    // и тут doc
    pub fn extract(&self, index: usize) -> f32 {
        self.0.extract
    }
}

Осознать, что это действительно лучший способ, было не тривиально...

src/vec4f.rs Outdated
/// Represents a packed vector of 4 single-precision floating-point values. [`__m128`] wrapper.
#[derive(Clone, Copy)]
pub struct Vec4f {
xmm: __m128,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А ты уверен, что все процессоры подерживают все инструкции, которые ты тут исопльзовал?
Не нужно cfg проверить какой-нибудь, и fallback на тупую реализацию?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я вроде ручками проверил, но да, надо это как-то затестить

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Owner Author

@NamorNiradnug NamorNiradnug Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

А, в этом смысле... Я тут всё пишу с мыслью, что у меня есть хотя бы sse, и этот модуль в принципе подключается в #cfg(sse), и вроде все инструкции SSE-шные.

Я комментарием в гитхабе писал проблему: нужно как-то проверять, что у меня действительно не используются AVX-фичи на сборке без AVX. Там на все интринзики, конечно, есть #[target_feature(enable = "avx")], но это просто добавляет мне UB в код ¯\_(ツ)_/¯. Как это делать — пока что не знаю. Можете подсказать, если знаете?

src/vec8f.rs Outdated Show resolved Hide resolved
src/vec4f.rs Outdated Show resolved Hide resolved
src/vec8f.rs Outdated Show resolved Hide resolved
src/vec4f/mod.rs Outdated Show resolved Hide resolved
src/vec4f/mod.rs Show resolved Hide resolved
src/vec4f/mod.rs Outdated Show resolved Hide resolved
src/vec4f/mod.rs Outdated Show resolved Hide resolved
src/vec4f/mod.rs Show resolved Hide resolved
@NamorNiradnug NamorNiradnug merged commit dd8c27f into main Jan 7, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace check with clippy in CI
3 participants