Fastest possible saturation ???
Author Message Fastest possible saturation ???

Quote:

> what would be the fastest code for staturating a signed 32bit value to
> an 8bit unsigned value ?
> (no MMX instructions !!!)

> the problem:

>   var:=input;
>   IF (var<0) THEN var:=0;
>   IF (var>255) THEN var:=255;
>   output:=var;

> in assembler:

>   MOV EAX,input {signed 32bit value)
>   OR EAX,EAX

>   MOV EAX,0

>   TEST EAX,0FFFFFF00h

>   MOV EAX,255

>   MOV output,AL

>   MOV EAX,input
>   TEST EAX,0FFFFFF00h
>   SETZ BL
>   SETS CL
>   DEC BL
>   OR AL,BL
>   MOV output,AL

Here's an alternative, first in C:

lo = (-n) >> 31;        // 0 if the number was negative
hi = (255 - n) >> 31; // -1 if the number was greater than 255
return (unsigned char) ((lo & n) | hi);

asm:

mov ebx,255
xor ecx,ecx

xor ecx,eax           ;; NOT n
sub ebx,eax           ;; 255 - n

sbb ebx,ebx           ;; -1 if (n > 255)
sar ecx,31            ;; 0 if (n < 0)

and eax,ecx

or eax,ebx

Alternatively:

cmp eax,256           ; carry if (n < 256)
mov ebx,eax

sbb ecx,ecx           ; -1 if (n < 256)
xor ebx,-1            ; Invert the sign bit

sar ebx,31            ; 0 if (n < 0)
xor ecx,-1            ; -1 if (n >= 256)

or eax,ecx            ; Make it 255 if too large

and eax,ebx           ; Clamp to zero if negative

The second version seem to pair perfectly on a Pentium, on a P6 both
should be equal.

Finally, you can try to use a conditional move version:

mov ebx,255           ; Upper limit
cmp eax,255           ; Check for too large input

cmovg eax,ebx         ; Set to 255 if (n > 255)
xor ebx,ebx

test eax,eax
cmovs eax,ebx

This is also 5 cycles, since each of the CMOVcc instruction require two
cycles.

Terje

--

Using self-discipline, see http://www.*-*-*.com/
"almost all programming can be viewed as an exercise in caching"

Thu, 08 Aug 2002 03:00:00 GMT

 Page 1 of 1 [ 1 post ]

Relevant Pages