LINUX.ORG.RU

Правильно ли я пишу на Rust?

 , ,


1

6

Часто мелькает Rust и в новостях, и в темах. Решил попробовать переписать один тест с С на Rust. Для сравнения написал вариант и на C++. На Rust получилось в 4+ раза медленнее, чем на С и в 2+ раза медленнее, чем на C++. Есть подозрение, что я делаю что-то неправильно, но не знаю что. Помогите, пожалуйста, разобраться.

UPD. Мои цифры:

$ gcc c_v1.c -Ofast -march=native
$ ./a.out 3000
16.439091
-287.250083
$ g++ cpp_v2.cpp -Ofast -march=native
$ ./a.out 3000
31.3826
-287.25
$ rustc rust_v1.rs -C opt-level=3 -C target-cpu=native
$ ./rust_v1 3000
71.570172703s
-287.2500833333321

тут мелькало мнение, что мы несём с собой умение кодить тем-то языком в другие, А вот они, как раз, требуют другого подхода ))) Или знаний ))) А так - benchmark на простую хрень.

n1rdeks ()
Ответ на: комментарий от n1rdeks

тут мелькало мнение, что мы несём с собой умение кодить тем-то языком в другие

Это описывается термином «Программируйте с использованием языка, а не языке».

rumgot ★★★★★ ()
Ответ на: комментарий от andalevor

Это не бенчи. Ну и у вас c++ код не эквивалентен сишному, поэтому и медленнее.

Ну и сравнивать нужно без fast-math, ибо это фича компилятора, а не языка.

RazrFalcon ★★★★★ ()
Последнее исправление: RazrFalcon (всего исправлений: 1)

В расте проверка границ в векторе. Можешь ради интереса заменить квадратные скобки на at() в С++ и показать сколько получится

Ну или в расте get_unchecked+unsafe

vertexua ★★★☆☆ ()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Ну и сравнивать нужно без fast-math, ибо это фича компилятора

В Rust использовались аналогичные intrinsic.

Ну и у вас c++ код не эквивалентен сишному

Там рядом есть аналогичный. За вычетом restrict, которого нет в С++.

andalevor ()

Характерно, что среди уже поступивших предложений от растосектантов есть советы типа «попробуй замедить код на C/C++», но пока нет совета, как ускорить код на Rust.

anonymous ()
Ответ на: комментарий от anonymous

Я посоветовал или то, или то, на выбор. Если применить совет, то будет понятно что в этом основная причина - проверки границ

vertexua ★★★☆☆ ()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от vertexua

основная причина - проверки границ

Похоже на то. Замена [] на at() в варианте С++ дало такое же время как у Rust(71.75). Но вот наоборот что-то не совсем получается, я добавил get_unchecked, вариант Rust ускорился(41.40), но всё равно немного медленнее, чем С++. Может быть что-то ещё есть?

andalevor ()

Что получается с

    for (i, c_row) in c.chunks_exact_mut(n).enumerate() {
        for (j, c_val) in c_row.iter_mut().enumerate() {
            let a_row = &a[i*n..i*n+n];
            let t_row = &t[j*n..j*n+n];
            *c_val = a_row.iter().zip(t_row.iter()).map(|(&a,&t)| unsafe{ fmul_fast(a,t) } ).sum();
        }
    }
red75prim ★★ ()
Последнее исправление: red75prim (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Ну и сравнивать нужно без fast-math, ибо это фича компилятора, а не языка.

Лолшто? Ну давай не будем использовать O3 тоже этож тоже фича компилятора…

pon4ik ★★★★★ ()

Даже пожалуй вот так:

    for (i, c_row) in c.chunks_exact_mut(n).enumerate() {
        for (j, c_val) in c_row.iter_mut().enumerate() {
            let a_row = &a[i*n..i*n+n];
            let t_row = &t[j*n..j*n+n];
            *c_val = a_row.iter().zip(t_row.iter()).fold(0.0, |sum, (&a,&t)| unsafe{ fadd_fast(fmul_fast(a,t), sum) } );
        }
    }
red75prim ★★ ()
Ответ на: комментарий от andreyu

У меня на машине C-шный вариант ТС-а с restrict дает 22s, а он же, но без restrict — уже 28s. Разница только в наличии/отсутствии этого ключевого слова.

Так что отсутствие в C++ restrict-а, плюс дополнительные поля в std::vector, которые дают другую раскладку данных в памяти, вероятно, и приводят к такой разнице между C и C++.

eao197 ★★★★★ ()
Ответ на: комментарий от pon4ik

Лолшто? Ну давай не будем использовать O3 тоже этож тоже фича компилятора…

Да уж, растишники поражают своей непосредственностью и наивностью.

anonymous ()
Ответ на: комментарий от eao197

дополнительные поля в std::vector, которые дают другую раскладку данных в памяти, вероятно, и приводят к такой разнице между C и C++.

Именно. В плюсовом тесте измеряется не производительность языка, а производительность и размер кеша.

andreyu ★★★★★ ()