префиксный инкремент

Модератор: Модераторы разделов

Аватара пользователя
Folderx
Сообщения: 296
ОС: fedora, mandriva

Re: префиксный инкремент

Сообщение Folderx »

опять подменили x++

x++ - это постфиксное выражение, у них свои свойства
++x - это одноместное выражение, у них свои свойства

и x++ + x++ в сравнении с ++x + ++x совсем по-разному работают
каким образом ++x + ++x + ++x может выполнится по-другому и получатся разные результаты в разных компиляторах (это из первого вопроса всё) ?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: префиксный инкремент

Сообщение drBatty »

Folderx писал(а):
17.04.2009 06:05
опять подменили x++

x++ - это постфиксное выражение, у них свои свойства
++x - это одноместное выражение, у них свои свойства
вы наверное довольно молоды :)
это одна и та-же операция, раньше все регистры CPU такое допускали, сейчас, правда, только esp так может. постфиксные и префиксные операции очень удобны для индексной арифметики, которая и используется в С и в С++ - разные алгоритмы поиска, сортировки, и прочего, что в других языках спрятано в библиотеках и разных регулярных выражениях. Без этих операций даже простейший стек не сделать, точнее можно, только работать будет в два раза дольше.

Код: Выделить всё

void push(int x)
{stack[++sp] = x;}

int pop()
{return stack[sp--];}

каждая из этих функций, во времена создания Си, превращалась компилятором в 1 команду процессора. так в языке это и осталось... Если вы думаете, что x++ выполняется как

Код: Выделить всё

tmp = x;
x = x+1;
return tmp;

вы сильно заблуждаетесь, это не bash ;)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Folderx
Сообщения: 296
ОС: fedora, mandriva

Re: префиксный инкремент

Сообщение Folderx »

(drBatty) писал(а):это одна и та-же операция

а её результат ? он выходит за её пределы ?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: префиксный инкремент

Сообщение drBatty »

Folderx писал(а):
17.04.2009 15:38
(drBatty) писал(а):это одна и та-же операция

а её результат ? он выходит за её пределы ?

конечно! вопрос - когда.
вы почему-то полагаете, что
1)сначала выполняются ++,
2)а потом берётся результаты,
3)а потом складывается.

Но это не так. Нет такого требования в стандарте.

возможно такое:
1)сначала выполняется один из ++
2)берётся его результат(6)
3)потом выполняется второй ++
4)берётся его результат(7)
5)складывается, ответ 13

или
1)компилятор решает копирует x в х2
2)выполняется первый ++х, и берётся его результат(6)
3)выполняется второй ++х2, и берётся его результат(6)
4) сумма равна 12
Этот вариант хорош, если у нас 2 ALU, а начиная с Pentium1 это так везде. Можно п2 и п3 выполнить за 1 такт в U и в V трубе. Правда есть ещё п1, но его мы можем совместить с почти любой другой операцией, вот только с п4 не получится совместить(а первом пне, в новых может быть и получится). Даже странно, почему получается именно 14, а не 12! (на наших компиляторах) :) Впрочем это слишком простой пример, я уверен, что более сложные выражения вовсе не подчиняются вашему правилу (выше уже дан пример, немного помучившись вы найдёте таких ещё сколько нужно, причём только с ++х и только с х++, как вам захочется).

PS: в данном случае у выражения есть 2 результата:
1)сама сумма, непонятно какая(12,13,14)
2)новое значение x, оно равно в точности 7.
Компилятор обязан вычислить оба, причём второе он обязан вычислить правильно. Потому семёрка получится обязательно. Что касается суммы, то компилятор просто удваивает эту семёрку. Думать о результате суммы компилятор не обязан, ему важно получить 7, вот он и оптимизирует два ++ в одно +2(по времени это столько-же, на нынешних CPU). Те варианты где получается 12 или 13 требуют двух инкрементов, а это всё-же дольше одного сложения, даже в случае если инкременты распаленны(второе сложение нельзя спарить не с чем, так-как оно объеденяет результаты с двух конвейров).

Код: Выделить всё

add eax, 2
mov ecx, eax
add eax, ecx

это занимает 3 такта, однако на другом ALU за те-же 3 такта может быть выполнены другие 3 команды.
последовательность

Код: Выделить всё

mov eax, ecx
inc eax
inc ecx
add eax, ecx

тоже выполнится за 3 такта, однако только первая команда может с чем-то спарится.
вторая уже спарена с третий, а четвёртая не спарена не с чем. да и x'ы у нас получились 2 штуки по 6, а нам нужен 1 по 7 :(
вариант когда 13 получится анализируйте сами :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Folderx
Сообщения: 296
ОС: fedora, mandriva

Re: префиксный инкремент

Сообщение Folderx »

а, ну ясно терь
операция + может выполняться разными способами, а не одним
и это при одинаковой последовательности вычисления своих операндов
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: префиксный инкремент

Сообщение drBatty »

Folderx писал(а):
19.04.2009 11:59
а, ну ясно терь
операция + может выполняться разными способами, а не одним
и это при одинаковой последовательности вычисления своих операндов

не, + только одним способом. а вот ++ - двумя, так-как ++ имеет 2 результата, а не один.

ЗЫЖ когда создавали C, были компы PDP, я на таких даже работал(хотя я тогда ещё кроме бэйсика ничего не умел, и в школе учился), там это делалась за 2 команды:
mov R2, INCREMENT:[R1]
add R2, INCREMENT:[R1]

и получалось у отцов основателей именно 13(а я уверен, что про эту фишку они знали) ;)

ЗЗЫЖ про асм - чисто мои предположения, может это и не совсем так. я точно знаю только 2 вещи:
1)компилятор придерживается стандарта, а в стандарте ++ и + не упомянуты как точки следования, значит компилятор может как угодно считать.
2)если точки следования нет, то её надо сделать:

Код: Выделить всё

++x, ++x;
y=x+x;

такой код будет давать 14 на любом компе.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
trinimak
Сообщения: 126
ОС: archlinux

Re: префиксный инкремент

Сообщение trinimak »

В общем, нужно стараться не использовать такого рода конструкции, в которых могут возникать неопределенности.
маленький кавайный линуксоид ^_^
Спасибо сказали: