string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 27.05.19 17:36
Оценка:
В теории по ссылке эффективнее т.к. передача всего одного указателя вместо двух.
В интернетах пишут, что незачем заморачиваться класс и так маленький и по значению сойдёт.
Что думаете ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: string_view по ссылке или по значению
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 27.05.19 18:01
Оценка: 1 (1) +3
Здравствуйте, _NN_, Вы писали:

_NN>Что думаете ?


По значению
Re: string_view по ссылке или по значению
От: watchmaker  
Дата: 27.05.19 18:11
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>В теории по ссылке эффективнее

Определи, что значит "эффективнее".
Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I .

_NN>т.к. передача всего одного указателя вместо двух.

Ну да. А заодно потребует от вызываемой функции материализовать экземпляр, ссылку на который нужно будет передать в вызываемую функцию.
Разменяли запись в регистр на аллокацию объекта в памяти. Аллокация, конечно, в стеке, но всё равно такой курс размена обычно невыгодный.

_NN>Что думаете ?

Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.
Re[2]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 27.05.19 18:17
Оценка:
Здравствуйте, watchmaker, Вы писали:

Ну вот я передавал всегда по значению, а тут кто-то посоветовал по ссылке.
По значению действительно эффективнее.
https://gcc.godbolt.org/z/L3ObMK
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 27.05.19 18:28
Оценка:
Здравствуйте, watchmaker, Вы писали:

_NN>>В теории по ссылке эффективнее

W>Определи, что значит "эффективнее".
W>Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I .
В этом примере как раз sum_chars_ref гораздо короче
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: string_view по ссылке или по значению
От: watchmaker  
Дата: 27.05.19 18:39
Оценка:
Здравствуйте, _NN_, Вы писали:

W>>Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I .

_NN>В этом примере как раз sum_chars_ref гораздо короче :))
Удивительно, но длина машинного кода не является единственным определяющим фактором времени его работы :)
Важно, что чтений из памяти sum_chars_ref делает вдвое больше. И плюс всякие оптимизации, завязанные на знание числа итераций цикла (unroll, vectorize), отпадают.
То что он короче — это следствие того, что компилятор сдался и просто признал, что его знаний не хватит чтобы понять как такую фигню заставить быстро работать.
Re: string_view по ссылке или по значению
От: Zhendos  
Дата: 27.05.19 23:56
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В теории по ссылке эффективнее т.к. передача всего одного указателя вместо двух.

_NN>В интернетах пишут, что незачем заморачиваться класс и так маленький и по значению сойдёт.
_NN>Что думаете ?

1. Есть CppCoreGuidelines описывающий что передавать по ссылке, а что по значению
и string_view как раз попадает под категорию "cheap", так как два машинных слова.

http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f16-for-in-parameters-pass-cheaply-copied-types-by-value-and-others-by-reference-to-const

2. Вообще передача по ссылке выглядит безумием на x86-64,
вот мы вычислили string_view и у нас есть два значения (указатель и длина),
в двух регистрах, вместо того, чтобы сразу вызывать (перейти по адресу)
вызываемой функции, мы кладем эти регистры в стек, записываем адрес
(куда положили) в регистр, вызываем функцию, та чтобы работать с string_view
достает данные из стека, загружая их в два регистра.
Безумие какое-то получается.

3. Ну aliasing как ту уже заметили (и он даже работает если всего один аргумент типа const string_view &),
например в середине функции, которой передали "const string_view &" вызывается какая-то функцию,
постэфеккты которой компилятор не может предсказать, компилятор тогда сгенерирует код,
который перечитает string_view из памяти, после вызова этой функции, а то вдруг она поменяла значение.
Re[4]: string_view по ссылке или по значению
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 28.05.19 01:55
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Удивительно, но длина машинного кода не является единственным определяющим фактором времени его работы

W>Важно, что чтений из памяти sum_chars_ref делает вдвое больше. И плюс всякие оптимизации, завязанные на знание числа итераций цикла (unroll, vectorize), отпадают.

Очень заинтриговал! А не можешь немного рассказать почему это:

        movsbq  (%rsi,%r9), %rax
        addq    %rcx, %rax
        movq    %rax, (%rdx)
        movsbq  1(%rsi,%r9), %rcx
        addq    %rax, %rcx
        movq    %rcx, (%rdx)
        movsbq  2(%rsi,%r9), %rax
        addq    %rcx, %rax
        movq    %rax, (%rdx)
        movsbq  3(%rsi,%r9), %rcx
        addq    %rax, %rcx
        movq    %rcx, (%rdx)
        addq    $4, %r9
        cmpq    %r9, %rdi
        jne     .LBB0_8
        testq   %r8, %r8
        je      .LBB0_6
.LBB0_4:
        addq    %r9, %rsi
        xorl    %eax, %eax
.LBB0_5:                                # =>This Inner Loop Header: Depth=1
        movsbq  (%rsi,%rax), %rdi
        addq    %rdi, %rcx
        movq    %rcx, (%rdx)


быстрее этого:
        movq    (%rsi), %rcx
        xorl    %edx, %edx
.LBB1_2:                                # =>This Inner Loop Header: Depth=1
        movsbq  (%r8,%rdx), %rax
        addq    %rax, %rcx
        movq    %rcx, (%rsi)


По мне так мы имеем довольно схожий набор из movsbq и movq в обоих случаях и в первом варианте делаем куда больше обращений к памяти.
Re[5]: string_view по ссылке или по значению
От: reversecode google
Дата: 28.05.19 02:56
Оценка: 10 (1)
потому что в конвеер грузится сразу доступ к 4 елементам в случае если длинна кратна 4
а в цикле ниже только по одному
и это медленее для цпу

вообще странно слышать такой вопрос от вас
кем вы в лк работали ?
Re[6]: string_view по ссылке или по значению
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 28.05.19 03:20
Оценка:
Здравствуйте, reversecode, Вы писали:

R>потому что в конвеер грузится сразу доступ к 4 елементам в случае если длинна кратна 4

R>а в цикле ниже только по одному
R>и это медленее для цпу

Спасибо, да, разумно.

R>вообще странно слышать такой вопрос от вас

R>кем вы в лк работали ?

Странно? Да ни сколько, работа в ЛК совсем не значит что ты занимаешься оптимизациями В ЛК я был "Mac Applications Development Group Manager".
Re[2]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 28.05.19 06:16
Оценка:
Здравствуйте, watchmaker, Вы писали:

А что насчёт возврата ?
Применимы ли тут аналогичные выводы ?
Судя по дисассемблеру как раз возврат ссылки эффективнее будет:

//         mov     rax, rdi
string_view const& as_view(string_view const& view) noexcept { return view; }

//         mov     rdx, rsi
//         mov     rax, rdi
string_view as_view2(string_view view) noexcept { return view; }
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: string_view по ссылке или по значению
От: T4r4sB Россия  
Дата: 28.05.19 06:52
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.


Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.
Re[3]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 28.05.19 06:57
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, watchmaker, Вы писали:


W>>Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.


TB>Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.


Можете пояснить при чём тут Виндоуз и где например Линукс лучше в данном случае ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: string_view по ссылке или по значению
От: T4r4sB Россия  
Дата: 28.05.19 07:01
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Можете пояснить при чём тут Виндоуз и где например Линукс лучше в данном случае ?


Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))
Это мусрософт такую хренатень придумал.
Re[3]: string_view по ссылке или по значению
От: Zhendos  
Дата: 28.05.19 07:27
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, watchmaker, Вы писали:


_NN>А что насчёт возврата ?

_NN>Применимы ли тут аналогичные выводы ?
_NN>Судя по дисассемблеру как раз возврат ссылки эффективнее будет:

_NN>
_NN>//         mov     rax, rdi
_NN>string_view const& as_view(string_view const& view) noexcept { return view; }

_NN>//         mov     rdx, rsi
_NN>//         mov     rax, rdi
_NN>string_view as_view2(string_view view) noexcept { return view; }
_NN>


Так ведь метод же вызвали не просто так, а с string_view
будут работать, а для этого в первом случае загрузят данные из памяти
в два регистра, а во втором просто начнут использовать эти два регистра.
Разве не очевидно какой вариант быстрее?
Re[5]: string_view по ссылке или по значению
От: _NN_ www.nemerleweb.com
Дата: 28.05.19 07:28
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, _NN_, Вы писали:


_NN>>Можете пояснить при чём тут Виндоуз и где например Линукс лучше в данном случае ?


TB>Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))

TB>Это мусрософт такую хренатень придумал.

Вы про ABI x64 винды ?
Aggregates (other) By pointer. First 4 parameters passed as pointers in RCX, RDX, R8, and R9

https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: string_view по ссылке или по значению
От: T4r4sB Россия  
Дата: 28.05.19 07:34
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Вы про ABI x64 винды ?

_NN>Aggregates (other) By pointer. First 4 parameters passed as pointers in RCX, RDX, R8, and R9

Да-да-да. У вас не получится передать стрингвью по значению, в ШИНДОШЫ за вас всё решили и избавили вас от моральных страданий.
Re[6]: string_view по ссылке или по значению
От: T4r4sB Россия  
Дата: 28.05.19 07:40
Оценка:
Здравствуйте, _NN_, Вы писали:

Вот пример:
#include <cstdio>

struct string_view {
  const char* chars;
  size_t length;
};

extern"C" void print(struct string_view sv) {
  for (size_t i=0; i<sv.length; ++i) {
    printf("%c", sv.chars[i]);
  }
};


clang hello.cpp -o hello.ll -S -emit-llvm -O3

define dso_local void @print(%struct.string_view* nocapture readonly) local_unnamed_addr #0 {
  %2 = getelementptr inbounds %struct.string_view, %struct.string_view* %0, i64 0, i32 1
  %3 = load i64, i64* %2, align 8, !tbaa !8
  %4 = icmp eq i64 %3, 0
  br i1 %4, label %7, label %5

; <label>:5:                                      ; preds = %1
  %6 = getelementptr inbounds %struct.string_view, %struct.string_view* %0, i64 0, i32 0
  br label %8

; <label>:7:                                      ; preds = %8, %1
  ret void

; <label>:8:                                      ; preds = %5, %8
  %9 = phi i64 [ 0, %5 ], [ %15, %8 ]
  %10 = load i8*, i8** %6, align 8, !tbaa !14
  %11 = getelementptr inbounds i8, i8* %10, i64 %9
  %12 = load i8, i8* %11, align 1, !tbaa !15
  %13 = sext i8 %12 to i32
  %14 = tail call i32 @putchar(i32 %13)
  %15 = add nuw i64 %9, 1
  %16 = load i64, i64* %2, align 8, !tbaa !8
  %17 = icmp ult i64 %15, %16
  br i1 %17, label %8, label %7
}
Re[5]: string_view по ссылке или по значению
От: watchmaker  
Дата: 28.05.19 07:46
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB> Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.

Возможность передавать структуры по значению — это свойство языка, а не ABI.
Наверное в вышепроцитированном утверждении какое-то слово пропущено (например, "через регистры" или что-то ещё)

TB>Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))

Если сравнивать win c win, то вроде получается не хуже: https://godbolt.org/z/af28Dy
Сходу видна только проблема с тем, что если объект не модифицируется, а передаётся дальше как есть (как в последней паре функций с рекурсией), то получается плохо с копированием его на стек на каждой итерации. Но и для systemV abi аналогичный пример можно придумать (да на самом деле даже этот подойдёт).

А ты про какой сценарий говоришь?
Re[6]: string_view по ссылке или по значению
От: T4r4sB Россия  
Дата: 28.05.19 07:58
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Возможность передавать структуры по значению — это свойство языка, а не ABI.


Проблема всех компиляторов С/С++ под винду-64, так лучше?

W>Наверное в вышепроцитированном утверждении какое-то слово пропущено (например, "через регистры" или что-то ещё)


TB>>Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))

W>Если сравнивать win c win, то вроде получается не хуже: https://godbolt.org/z/af28Dy
W>А ты про какой сценарий говоришь?
Ой, там асм. Я уже разучился его понимать. В ЛЛВМ лучше видно. Что передача по значению превращается в передачу по структуре.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.