· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Оптимизация a in [i1..i2]

Посл.отвђт Сообщенiе


Дата: Апр 20, 2004 15:48:01

Посмотрел, какой код генерит делфи для проверки находится ли dword (как знаковый, так и беззнаковый) в интервале [i1..i2] (i1, i2 - константы). Похоже, получается так:
add eax, -i1
sub eax, i2-i1+1
jnb NotInRange

Точно также и для word и для байт (используется ax и al)
Это конечно лучше, чем два сравнения и два перехода и хотелось бы писать подобным образом. Возникает вопрос об области применимости алгоритма, т.е. при каких i1 и i2 он работоспособен (например, при i1=-2147483648, i2=2147483647 он не работает)
В делфи этот вопрос не стоит, там макс. интервал [0..255]

Что думают по этому поводу знающие люди?


Дата: Апр 20, 2004 18:45:42

Далее идет цитирование (сплошняком) из книги Hackers Delight, Henry S. Warren, Jr.


****************
4-1 Checking Bounds of Integers


By "bounds checking" we mean to verify that an integer x is within two bounds a and b—that is, that

a <= x <= b

We first assume that all quantities are signed integers.

An important application is the checking of array indexes. For example, suppose a one-dimensional array A can be indexed by values from 1 to 10. Then, for a reference A(i), a compiler might generate code to check that

1 <= i <= 10

and to branch or trap if this is not the case. In this section we show that this check can be done with a single comparison, by performing the equivalent check [PL8]:

i - 1 <=u 9

This is probably better code, because it involves only one compare-branch (or compare-trap), and because the quantity i - 1 is probably needed anyway for the array addressing calculations.

Does the implementation

a <= x <= b => x - a <=u b - a

always work, even if overflow may occur in the subtractions? It does, provided we somehow know that a <= b. In the case of array bounds checking, language rules may require that an array not have a number of elements (or number of elements along any axis) that are 0 or negative, and this rule can be verified at compile time or, for dynamic extents, at array allocation time. In such an environment, the transformation above is correct, as we will now show.

It is convenient to use a lemma, which is good to know in its own right.

Lemma. If a and b are signed integers and a <= b, then the computed value b - a correctly represents the arithmetic value b - a, if the computed value is interpreted as unsigned.

Proof. (Assume a 32-bit machine.) Because a <= b, the true difference b - a is in the range 0 to (231 - 1) - (-231) = 232 - 1. If the true difference is in the range 0 to 231 - 1, then the machine result is correct (because the result is representable under signed interpretation), and the sign bit is off. Hence the machine result is correct under either signed or unsigned interpretation.

If the true difference is in the range 231 to 232 - 1, then the machine result will differ by some multiple of 232 (because the result is not representable under signed interpretation). This brings the result (under signed interpretation) to the range -231 to -1. The machine result is too low by 232, and the sign bit is on. Reinterpreting the result as unsigned increases it by 232, because the sign bit is given a weight of +231 rather than -231. Hence the reinterpreted result is correct.

The "bounds theorem" is

Theorem. If a and b are signed integers and a <= b, then

Equation 1

a <= x <= b = x - a <=u b - a

Proof. We distinguish three cases, based on the value of x. In all cases, by the lemma, since a <= b, the computed value b - a is equal to the arithmetic value b - a if b - a is interpreted as unsigned, as it is in Equation (1).

Case 1, x < a: In this case, x - a interpreted as unsigned is x - a + 232. Whatever the values of x and b are (within the range of 32-bit numbers),

x + 232 > b

Therefore

x - a + 232 > b - a

and hence

x - a >u b - a

In this case, both sides of Equation (1) are false.

Case 2, a <= x <= b: Then, arithmetically, x - a <= b - a. Because a <= x, by the lemma x - a equals the computed value x - a if the latter is interpreted as unsigned. Hence

x - a <=u b - a

that is, both sides of Equation (1) are true.

Case 3, x > b: Then x - a > b - a. Because in this case x > a (because b > a), by the lemma x - a equals the value of x - a if the latter is interpreted as unsigned. Hence

x - a >u b - a

that is, both sides of Equation (1) are false.

The theorem stated above is also true if a and b are unsigned integers. This is because for unsigned integers the lemma holds trivially, and the above proof is also valid.

Below is a list of similar bounds-checking transformations, with the one of the theorem above stated again. These all hold for either signed or unsigned interpretation of a, b, and x.

Equation 2

if (a <= b) then a <= x <= b
= x - a <=u b - a = b - x <=u b - a
if (a <= b) then a <= x < b
= x - a <u b - a
if (a <= b) then a < x <= b
= b - x <u b - a
if (a < b) then a < x < b
= x - a - 1 <u < b - a - 1 = b - x - 1 <ub - a - 1

In the last rule, b - a - 1 may be replaced with b + ¬a.

There are some quite different transformations that may be useful when the test is of the form -2n-1 <= x <= 2n-1 - 1. This is a test to see if a signed quantity x can be correctly represented as an n-bit two's-complement integer. To illustrate with n = 8, the following tests are equivalent:

a. -128 <= x <= 127

b. x + 128 <=u 255

c. (x >>5 7) + 1 <= u 1

d. (x >>5 7) = (x >>5 31)

e. (x >>5 7) - (x >>5 31) = 0

f. (x << 24)>> 5 24 = x

g. x XOR (x >>5 31) <= 127

Equation (b) is simply an application of the preceding material in this section. Equation (c) is as well, after shifting x right seven positions. Equations (c)-(f) and possibly (g) are probably useful only if the constants in Equations (a) and (b) exceed the size of the immediate fields of the computer's compare and add instructions.

Another special case involving powers of 2 is

0 <= x <= 2n - 1 <=> (x >> u n) = 0

*****************************
Так что, как видишь, есть более интересные дороги ;)





Дата: Апр 21, 2004 11:41:45

volodya
Спасибо, многое прояснилось. Книжка, видимо, очень дельная, попробую найти.
Что означает <=u? То что числа сравниваются, как беззнаковые?
Что означает >>5? Может >>s - сдвиг с расширением знака?
Если я правильно понял, проверить a in [i1..i2] можно так:
sub  eax, i1      (или dec eax при i1=1, или совсем убрать при i1=0)
cmp  eax, i2-i1
jnbe NotInRange


Дата: Апр 21, 2004 18:08:52

u - да, как unsigned
5 - ошибся, это действительно s - signed


Дата: Апр 22, 2004 15:49:16

Хм.. не совсем уверен, что правильно понял что такое in [i1..i2] :(
Возможно, это будет полезно:

Is val>lowval and val<highval optomization?
More about ranges

ЗЫ
volodya, судя по тем цифиркам ^^ математика - это сила :)


Дата: Апр 22, 2004 17:06:25 · Поправил: Безпощадный даос

S_T_A_S_

Спасибо. Основательно они там к вопросу подошли.
А математика рулит:
  ;проверка на 0<=eax<=1023, никогда бы не догадался
  shr  eax, 10
  jnz  NotInRange


Дата: Апр 23, 2004 04:04:20 · Поправил: Black_mirror

BLOb
По моему все же лучше:
cmp eax,1023
ja NotInRange


Дата: Апр 23, 2004 05:55:30

Это больше по размеру


Дата: Апр 27, 2004 21:03:49 · Поправил: Безпощадный даос

Для тех кто тащится от маленького кода даю исходник сложения двух чисел !!! кто меньше !!!
элитарный клуб супер оптимизированного кода - там конкурся проводят...http://www.cybertrails.com/~fys/hugi/hcompo.htm
вот там черти сидят - зайдите в предыдущие посмотрите исходники - глазки из орбит полезут !!!

Брокен сворду привет !!!
.286                        
MODEL TINY                  
DATASEG                     
num1    DB '0098'           
simvol  DB '/code]              
num2    DB '0001'    
len equ $-num2       
CODESEG                     
        STARTUPCODE         
start:                      
        mov cl,len-1
        mov di,offset num1+len-1
next:                       
        std
        lodsb       
        sahf
        adc al,[di]         
        aaa
        lahf
        or al,30h
        stosb             
        loopnz next        
        mov dx,di         
        xchg ax,bp
        int 21h           
        ret
END


Дата: Апр 27, 2004 22:53:31

S_W_A_N

Что делает код, который вы привели ?


Дата: Апр 27, 2004 23:15:18

сложение num1 и num2 и вывод результата на экран я полагаю.


Дата: Апр 27, 2004 23:23:21

Mad_C
Это из комментариев следует. А на самом-то деле ? =)

ЗЫ
К тому же он не в тему здесь совсем >:|


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.085