В теории по ссылке эффективнее т.к. передача всего одного указателя вместо двух.
В интернетах пишут, что незачем заморачиваться класс и так маленький и по значению сойдёт.
Что думаете ?
Здравствуйте, _NN_, Вы писали:
_NN>В теории по ссылке эффективнее
Определи, что значит "эффективнее".
Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I .
_NN>т.к. передача всего одного указателя вместо двух.
Ну да. А заодно потребует от вызываемой функции материализовать экземпляр, ссылку на который нужно будет передать в вызываемую функцию.
Разменяли запись в регистр на аллокацию объекта в памяти. Аллокация, конечно, в стеке, но всё равно такой курс размена обычно невыгодный.
_NN>Что думаете ?
Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.
Здравствуйте, watchmaker, Вы писали:
_NN>>В теории по ссылке эффективнее W>Определи, что значит "эффективнее". W>Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I .
В этом примере как раз sum_chars_ref гораздо короче
Здравствуйте, _NN_, Вы писали:
W>>Например, код не будет быстрее. И даже можно утверждать, что часто будет медленнее. Ведь передача по ссылке запрещает много полезных оптимизаций, например из-за правил алиасинга в C++: https://godbolt.org/z/nso76I . _NN>В этом примере как раз sum_chars_ref гораздо короче :))
Удивительно, но длина машинного кода не является единственным определяющим фактором времени его работы :)
Важно, что чтений из памяти sum_chars_ref делает вдвое больше. И плюс всякие оптимизации, завязанные на знание числа итераций цикла (unroll, vectorize), отпадают.
То что он короче — это следствие того, что компилятор сдался и просто признал, что его знаний не хватит чтобы понять как такую фигню заставить быстро работать.
Здравствуйте, _NN_, Вы писали:
_NN>В теории по ссылке эффективнее т.к. передача всего одного указателя вместо двух. _NN>В интернетах пишут, что незачем заморачиваться класс и так маленький и по значению сойдёт. _NN>Что думаете ?
1. Есть CppCoreGuidelines описывающий что передавать по ссылке, а что по значению
и string_view как раз попадает под категорию "cheap", так как два машинных слова.
2. Вообще передача по ссылке выглядит безумием на x86-64,
вот мы вычислили string_view и у нас есть два значения (указатель и длина),
в двух регистрах, вместо того, чтобы сразу вызывать (перейти по адресу)
вызываемой функции, мы кладем эти регистры в стек, записываем адрес
(куда положили) в регистр, вызываем функцию, та чтобы работать с string_view
достает данные из стека, загружая их в два регистра.
Безумие какое-то получается.
3. Ну aliasing как ту уже заметили (и он даже работает если всего один аргумент типа const string_view &),
например в середине функции, которой передали "const string_view &" вызывается какая-то функцию,
постэфеккты которой компилятор не может предсказать, компилятор тогда сгенерирует код,
который перечитает string_view из памяти, после вызова этой функции, а то вдруг она поменяла значение.
Здравствуйте, watchmaker, Вы писали:
W>Удивительно, но длина машинного кода не является единственным определяющим фактором времени его работы W>Важно, что чтений из памяти sum_chars_ref делает вдвое больше. И плюс всякие оптимизации, завязанные на знание числа итераций цикла (unroll, vectorize), отпадают.
Очень заинтриговал! А не можешь немного рассказать почему это:
Здравствуйте, reversecode, Вы писали:
R>потому что в конвеер грузится сразу доступ к 4 елементам в случае если длинна кратна 4 R>а в цикле ниже только по одному R>и это медленее для цпу
Спасибо, да, разумно.
R>вообще странно слышать такой вопрос от вас R>кем вы в лк работали ?
Странно? Да ни сколько, работа в ЛК совсем не значит что ты занимаешься оптимизациями В ЛК я был "Mac Applications Development Group Manager".
Здравствуйте, watchmaker, Вы писали:
W>Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.
Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, watchmaker, Вы писали:
W>>Если нет веских причин передавать по ссылке, то передавать string_view всегда нужно по значению. Веские причины встречаются редко.
TB>Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.
Можете пояснить при чём тут Виндоуз и где например Линукс лучше в данном случае ?
Здравствуйте, _NN_, Вы писали:
_NN>Можете пояснить при чём тут Виндоуз и где например Линукс лучше в данном случае ?
Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))
Это мусрософт такую хренатень придумал.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, watchmaker, Вы писали:
_NN>А что насчёт возврата ? _NN>Применимы ли тут аналогичные выводы ? _NN>Судя по дисассемблеру как раз возврат ссылки эффективнее будет:
_NN>
Так ведь метод же вызвали не просто так, а с string_view
будут работать, а для этого в первом случае загрузят данные из памяти
в два регистра, а во втором просто начнут использовать эти два регистра.
Разве не очевидно какой вариант быстрее?
Здравствуйте, 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
Здравствуйте, _NN_, Вы писали:
_NN>Вы про ABI x64 винды ? _NN>Aggregates (other) By pointer. First 4 parameters passed as pointers in RCX, RDX, R8, and R9
Да-да-да. У вас не получится передать стрингвью по значению, в ШИНДОШЫ за вас всё решили и избавили вас от моральных страданий.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, T4r4sB, Вы писали:
TB> Убогое АБИ — веская причина? Виндуза не позволяет передавать такие вещи по значению.
Возможность передавать структуры по значению — это свойство языка, а не ABI.
Наверное в вышепроцитированном утверждении какое-то слово пропущено (например, "через регистры" или что-то ещё)
TB>Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись)))
Если сравнивать win c win, то вроде получается не хуже: https://godbolt.org/z/af28Dy
Сходу видна только проблема с тем, что если объект не модифицируется, а передаётся дальше как есть (как в последней паре функций с рекурсией), то получается плохо с копированием его на стек на каждой итерации. Но и для systemV abi аналогичный пример можно придумать (да на самом деле даже этот подойдёт).
Здравствуйте, watchmaker, Вы писали:
W>Возможность передавать структуры по значению — это свойство языка, а не ABI.
Проблема всех компиляторов С/С++ под винду-64, так лучше?
W>Наверное в вышепроцитированном утверждении какое-то слово пропущено (например, "через регистры" или что-то ещё)
TB>>Попробуй передать структурку по значению, собери ллвм под винду-64 для наглядности, посмотри в код и огорчись))) W>Если сравнивать win c win, то вроде получается не хуже: https://godbolt.org/z/af28Dy W>А ты про какой сценарий говоришь?
Ой, там асм. Я уже разучился его понимать. В ЛЛВМ лучше видно. Что передача по значению превращается в передачу по структуре.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте