avva: (Default)
[personal profile] avva
(эта запись будет интересна только программистам)

Расс Кокс рассказывает о супероптимизации - технике поиска самого быстрого куска кода путем полного перебора инструкций процессора (конечно, это работает только для очень коротких кусков кода). Любопытный пример там - самое быстрое воплощение функции знака (-1, 0 или 1 в зависимости от знака аргумента) на ассемблере 80x86. До такого вручную действительно додуматься нелегко:

cwd
neg ax
adc dx, dx

Здесь начальный аргумент лежит в ax, значение помещается в dx. Работает следующим образом: сначала cwd расширяет знак ax в dx, после чего в dx лежит -1, если аргумент отрицательный, а иначе 0. neg ax меняет знак ax, но это на самом деле неважно, а важно то, что эта инструкция помещает в флаг carry единицу, только если аргумент был ненулевой.

Наконец adc dx, dx складывает dx с самим собой, добавляет carry от второй инструкции, и помещает результат в dx. В результате выходит:

- если ax<0, то dx вначале -1, carry равен 1, результат равен -1*2+1 = -1 (во как!)
- если аx=0, то dx вначале 0, carry равен 0, результат 0*2+0=0
- если ax>0, то dx вначале 0, carry равен 1, результат 0*2+1=1

Красиво!

Date: 2008-02-27 09:38 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Альтернативных порядков вычисления значения выражения нет, но есть двойной побочный эффект: занесение значения в a. Преобразование выражения в промежуточное представление даст:

t1 = a ^ b;
t2 = b ^ t1;
t3 = a ^ t2;

a = t1;
b = t2;
a = t3;

Т.к. sequence points нет, то порядок двух присваиваний a не определен. Оптимизирующий компилятор вправе выбросить любое из двух. Это не означает, что существует хоть один, который выбрасывает "нужное", но тем не менее.

January 2026

S M T W T F S
    1 2 3
4 5678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 6th, 2026 10:32 am
Powered by Dreamwidth Studios