5

I'm wondering which is the best way to create two lookups table for square root and cubic root of float values in range [0.0, 1.0).

I already profiled the code and saw that this is quite a strong bottleneck of performances (because I need to compute them for several tenths of thousands of values each). Then I remembered about lookup tables and thought they would help me increasing the performance.

Since my values are in a small range I was thinking about splitting the range with steps of, let's say, 0.0025 (hoping it's enough) but I'm unsure about which should be the most efficient way to retrieve them.

I can easily populate the lookup table but I need a way to efficiently get the correct value for a given float (which is not discretized on any step). Any suggestions or well known approaches to this problem?

I'm working with a mobile platform, just to specify.

Thanks in advance

mskfisher
  • 3,291
  • 4
  • 35
  • 48
Jack
  • 131,802
  • 30
  • 241
  • 343
  • You want some kind of O(1) lookup? Then either reinterpret as int or do a simple math op that can give you an index in your table. – user703016 Apr 18 '12 at 18:27
  • What precision do you need and how much memory are you prepared to use for your lookup table? – David Heffernan Apr 18 '12 at 18:29
  • This values are then used to compute an height map which is split into 10 different height stripes so I guess to not need too much precision. I should investigate how much I exactly need after having an implemented solution. Regarding memory, since this is used just in a temporary step I don't have real strict requirements, but it's a mobile platform so I should be reasonable (<1MB?) – Jack Apr 18 '12 at 18:31
  • Since your values are ~1.0, have you tried using an approximation? They're generally much faster. – user703016 Apr 18 '12 at 18:32

4 Answers4

4

You have (1.0-0.0)/0.0025 = 400 steps

Just create a 400x1 matrix and access it by multiplying the float you want the square/cube to by 400.

For instance if you want to look up the square of 0.0075. Multiply 0.0075 by 400 and get 3 which is your index in the matrix

jelgh
  • 705
  • 1
  • 6
  • 22
1
double table_sqrt(double v)
{
    return table[(unsigned int)(v / 0.0025)];
}
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • 1
    Multiplication beats division performance, and depending on the compile options, the optimizer may not be able to make the change for you. – Ben Voigt Apr 18 '12 at 18:55
0

You could multiply the values by whatever precision that you want, and then use a hash-table since the results would be integral values.

For instance, rather than using a floating point key-value for something like 0.002, give yourself a precision of three or four decimal places, making your key value for 0.002 equal to 200 or 2000. Then you can quickly look-up the resulting floating point value for the square and cubic root stored in the hash-table key for the 2000 slot.

If you're wanting to also get values out of the non-discreet ranges in-between slots, you could use an array or tree rather than a hash-table so that you can generate "in-between" values by interpolating between the roots stored at two adjacent key-value slots.

Jason
  • 31,834
  • 7
  • 59
  • 78
0

If you only need to split into 10 different stripes, find the inputs which correspond to the thresholds between stripes, and use an unrolled binary search to test against those 9 values. Or is there additional computation required before the threshold test is done, so that the looked-up value isn't the final result.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720