специально переписал код, что-бы не вызывать memset, что-бы быстре работал:
unsigned int c = (count_in_page) >> 2;
for(;c>0; c--) *p++ = 0;
В итоге при компиляции "-O2 -m32", вижу на сайте gcc.godbolt.org (стоит gcc v12.2)
sub esp, 12
mov eax, DWORD PTR [esp+20]
shr eax, 2
je .L2
sub esp, 4
sal eax, 2
push eax
push 0
push DWORD PTR [esp+28]
call memset
add esp, 16
Я не указал, что процессор поддерживает SSE и попросил оптимизировать по скорости "-O2 -m32" почему он считает, что вызов memset будет быстрее ?
Почему он сам за меня решает, может я явно знаю, мне нужно заполнить 8-16 байт, за 2-4 операции *p++ = 0, это же будет явно быстрее чем "call memset" ?
Здравствуйте, maks1180, Вы писали:
M>специально переписал код, что-бы не вызывать memset, что-бы быстре работал:
M>Я не указал, что процессор поддерживает SSE и попросил оптимизировать по скорости "-O2 -m32" почему он считает, что вызов memset будет быстрее ? M>Почему он сам за меня решает, может я явно знаю, мне нужно заполнить 8-16 байт, за 2-4 операции *p++ = 0, это же будет явно быстрее чем "call memset" ?
Ну вообще часть работы компилятора и заключается в том чтобы вместо программиста решать
что и как будет быстрее работать. Для этого у него есть мат. модель целевого процессора,
в которой прописано что и как быстрее. Эту конкретную оптимизацию можно выключить с помощью
-fno-tree-loop-distribute-patterns
R>Переходите на нормальные тормознутые языки, где можно работать, а не дрочить на забивание полутора байтов нулями
Байтоёбслесарей не берут на нормальных языках писать.
Здравствуйте, maks1180, Вы писали:
M>специально переписал код, что-бы не вызывать memset, что-бы быстре работал
memset может быть существенно быстрей самодельного кода в некоторых случаях.
А какой конкретно случай тут -- компилятору не ведомо. И он подставляет обощённый
вариант. Если бы он знал значение c, или хотя бы возможный диапазон значений --
была бы совсем другая история.
Кроме того, если sizeof(*p) < sizeof(int) или _Alignof(*p) < _Alignof(int)
то тоже есть нюансы. Стандартный memset может иметь относительно сложную
реализацию для эффективной работы с большими блоками невыравненных данных,
например.
M>Я не указал, что процессор поддерживает SSE и попросил оптимизировать по скорости "-O2 -m32" почему он считает, что вызов memset будет быстрее?
А почему ты решаешь, что самодельный memset не будет медленее, специально оптимизированной версии из библиотеки?
M>Почему он сам за меня решает, может я явно знаю, мне нужно заполнить 8-16 байт, за 2-4 операции *p++ = 0, это же будет явно быстрее чем "call memset" ?
Здравствуйте, maks1180, Вы писали:
M>Почему он сам за меня решает, может я явно знаю, мне нужно заполнить 8-16 байт, за 2-4 операции *p++ = 0, это же будет явно быстрее чем "call memset" ?
Потому, что может.
Я думаю, если скастировать указатель в указатель на volatile байты, то gcc перестанет умничать.
Здравствуйте, maks1180, Вы писали:
M>специально переписал код, что-бы не вызывать memset, что-бы быстре работал: M>unsigned int c = (count_in_page) >> 2; M>for(;c>0; c--) *p++ = 0;
M>В итоге при компиляции "-O2 -m32", вижу на сайте gcc.godbolt.org (стоит gcc v12.2) M> sub esp, 12 M> mov eax, DWORD PTR [esp+20] M> shr eax, 2 M> je .L2 M> sub esp, 4 M> sal eax, 2 M> push eax M> push 0 M> push DWORD PTR [esp+28] M> call memset M> add esp, 16
M>Я не указал, что процессор поддерживает SSE и попросил оптимизировать по скорости "-O2 -m32" почему он считает, что вызов memset будет быстрее ? M>Почему он сам за меня решает, может я явно знаю, мне нужно заполнить 8-16 байт, за 2-4 операции *p++ = 0, это же будет явно быстрее чем "call memset" ?
Потому что отсутствие ошибок гораздо важнее ускорения на 0.001%. Поскольку код memset посмотрело множество людей, то вероятность найти в нём ошибку будет бесконечно мала по сравнению с кодом, который писал и видел всего один человек. Впрочем, эту оптимизацию можно отключить.
Здравствуйте, cppguard, Вы писали:
C>Потому что отсутствие ошибок гораздо важнее ускорения на 0.001%. Поскольку код memset посмотрело множество людей, то вероятность найти в нём ошибку будет бесконечно мала по сравнению с кодом, который писал и видел всего один человек.
Каких еще ошибок? В случае ошибки программиста компилятор берет на себя наглость смелость не указать на неё, а исправить по своему разумению? Вот это новость!
Здравствуйте, pagid_, Вы писали:
_>Каких еще ошибок? В случае ошибки программиста компилятор берет на себя наглость смелость не указать на неё, а исправить по своему разумению? Вот это новость!
Программист велосипедит memset. Компилятор это замечает и говорит: "Ты, конечно, рукожоп знатный, но давай таки я заменю твой кустарный мемсет на нормальный, реализацию которого проверили тысячи программистов по всему миру. А коли уж ты такой крутой, что напишешь лучше, то должен быть вкурсе про флаг --fno-lto, который отключает данную оптимизацию". Так понятно?
Здравствуйте, cppguard, Вы писали:
C>Программист велосипедит memset.
И что. с каких это пор функцией оптимизатора, да и компилятора в целом, стало исправление стиля программиста?
C>Компилятор это замечает и говорит: "Ты, конечно, рукожоп знатный, но давай таки я заменю твой кустарный мемсет на нормальный, реализацию которого проверили тысячи программистов по всему миру. А коли уж ты такой крутой, что напишешь лучше, то должен быть вкурсе про флаг --fno-lto, который отключает данную оптимизацию". Так понятно?
Так еще бы он что-то говорил. он как раз в тихушку наковырял.
Если бы это было предупреждение "А не лучше бы здесь использовать mеmset()", то и вопросов бы не было.
Нет, к стилю и велосипедостроению это отношения не имеет. Это действительно попытка оптимизации, и memset действительно в некоторых (многих ) случаях работает быстрее такого цикла. Но все же это тот случай, когда оптимизатор слишком много на себя берет и ведет себя неадекватно.
Здравствуйте, pagid_, Вы писали:
_>И что. с каких это пор функцией оптимизатора, да и компилятора в целом, стало исправление стиля программиста?
С тех пор, как разработчики компилятора так решили, очевидно же. Кому не нравится, тот пусть не использует. Free as free speech.
_>Так еще бы он что-то говорил. он как раз в тихушку наковырял. _>Если бы это было предупреждение "А не лучше бы здесь использовать mеmset()", то и вопросов бы не было.
Возможно, есть соответствующий флаг. Но даже без него достаточно предположить, что компилятор генерирует наиболее оптимальный код и дальше спокойно работать.
_>Нет, к стилю и велосипедостроению это отношения не имеет. Это действительно попытка оптимизации, и memset действительно в некоторых (многих ) случаях работает быстрее такого цикла. Но все же это тот случай, когда оптимизатор слишком много на себя берет и ведет себя неадекватно.
Это всего лишь программа. Так можно прикопаться к Inkscape, что та сплайны строит "как-то не так", оптимизирует или что-то там. Есть стандарт, компилятор старается ему соответствовать. Кто пишет под bare metal, должен быть в кусре таких дел. Как и тот, кто занимается тонкой оптимизацией.
Здравствуйте, cppguard, Вы писали:
C>С тех пор, как разработчики компилятора так решили, очевидно же. Кому не нравится, тот пусть не использует. Free as free speech.
Но они все же решили оптимизацию такую сделать, а вовсе не исправлять стиль программиста. Потому как результат никакого отношения к исправлению стиля не имеет, а вот на оптимизацию или её попытку похож.