Power Developer
https://www.powerdeveloper.org/forums/

How to use lookup tables in Altivec?
https://www.powerdeveloper.org/forums/viewtopic.php?f=23&t=181
Page 1 of 1

Author:  markos [ Mon Mar 14, 2005 7:08 am ]
Post subject:  How to use lookup tables in Altivec?

I'd like to rewrite these two functions
toLower(char *a)
toUpper(char *a)

in Altivec. Actually the original ones, take just a char as parameter, but where they're used, i could easily use vectorized functions for this. My guess is that they would be quite faster, but i'd have to use a lookup table, or sth like that. Could anyone give me some pointer on lookup tables in Altivec?

Thanks :-)

Konstantinos

Author:  dholm [ Mon Mar 14, 2005 7:05 pm ]
Post subject:  Re: How to use lookup tables in Altivec?

I wrote the following two functions for one of the CrabFire filters. They require no memory lookups so they will not pollute the data cache or hog the memory bus.
Code:
vector char vec_tolower(vector char str)
{
/* From Holger Bettag's table of constants */
vector char A = vec_rl(vec_splat_u8(4), vec_splat_u8(4));
vector char Z = vec_vor(vec_rl(vec_splat_u8(0xb), vec_splat_u8(0xb)), vec_splat_u8(0xb));
vector char diff = vec_rl(vec_splat_u8(1), vec_splat_u8(5));

vector bool char gt = vec_cmpgt(str, A);
vector bool char lt = vec_cmplt(str, Z);
vector bool char mask = vec_and(gt, lt);
vector char small = vec_add(str, diff);
return vec_sel(str, small, mask);
}
Code:
vector char vec_toupper(vector char str)
{
/* From Holger Bettag's table of constants */
vector char a = vec_rl(vec_splat_u8(3), vec_splat_u8(5));
vector char z = vec_avg(vec_splat_u8(0), vec_splat_u8(-13));
vector char diff = vec_rl(vec_splat_u8(1), vec_splat_u8(5));

vector bool char gt = vec_cmpgt(str, a);
vector bool char lt = vec_cmplt(str, z);
vector bool char mask = vec_and(gt, lt);
vector char small = vec_sub(str, diff);
return vec_sel(str, small, mask);
}

Author:  hobold [ Tue Mar 15, 2005 2:36 am ]
Post subject:  Re: How to use lookup tables in Altivec?

The most basic table lookup in AltiVec is a single vector permute: the 32 table entries reside in the 'left' and 'right' data vectors, and 16 indexes of 5 bit each reside in the 'permute control' vector.

To extend this to larger lookup tables, you need to compare and select based on the higher index bits. For example for a table with 64 entries, you do two 32 entry lookups as explained above. Then you mask out bit number 5 (the one valued as 32), compare the result to zero, and use the result of the comparison to select between the initial two lookups.

In practice you'd compute the boolean mask in parallel with the lookups (they happen in independent execution units).

As you can see, the decision tree can be recursively extended to include more significant bits, up to the limit of a full 8 bit lookup table. It looks unelegant, but it is almost always a win over scalar code indexing an actual char array in memory. The biggest problem is that the lookup table and the invariant values occupy a lot of vector registers. So there is not much headroom to do more calculation right before or after the lookup (you wouldn't want the compiler to spill and refill registers to/from memory).

Page 1 of 1 All times are UTC-06:00
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/