4

I am working on some code to be run on a very heterogeneous cluster. The program performs interval arithmetic using 3, 4, or 5 32 bit words (unsigned ints) to represent high precision boundaries for the intervals. It seems to me that representing some words in floating point in some situations may produce a speedup. So, my question is two parts:

1) Are there any guarantees in the C11 standard as to what range of integers will be represented exactly, and what range of input pairs would have their products represented exactly? One multiplication error could entirely change the results.

2) Is this even a reasonable approach? It seems that the separation of floating point and integer processing within the processor would allow data to be running through both pipelines simultaneously, improving throughput. I don't know much about hardware though, so I'm not sure that the pipelines for integers and floating points actually are all that separate, or, if they are, if they can be used simultaneously.

I understand that the effectiveness of this sort of thing is platform dependent, but right now I am concerned about the reliability of the approach. If it is reliable, I can benchmark it and see, but I am having trouble proving reliability. Secondly, perhaps this sort of approach shows little promise, and if so I would like to know so I can focus elsewhere.

Thanks!

Jack
  • 169
  • 7
  • What do you mean by "a very heterogeneous cluster"? Do you have several different processors that run parts of your code simultaneously? – anatolyg Mar 10 '15 at 10:11
  • I am breaking down a large project into several different programs, each of which I will manually install and run on anywhere from 1 to a few dozen systems, depending on the expected execution time. There are various types of x86-64, both intel and amd, and some of it can be ran on gpu, that will be run with mostly terascale 2 and tesla (the equipment is kinda old, but that's what I've got to work with). I am also going to benchmark portions that are bottlenecked by scattered memory on powerpc g4, I'll see if it is practical to use some older systems on those parts. – Jack Mar 10 '15 at 10:36
  • 1
    Regarding the separation of floating-point and integer pipelines: if you are going to use SSE, all variants of it reuse the same registers for `float` and `int` calculations, so cannot work simultaneously. I don't know about GPU though. – anatolyg Mar 10 '15 at 10:59
  • "any guarantees in the C11 standard as to what range of integers will be represented exactly" --> Use fixed width integer types like `int32_t` and `uint64_t`. – chux - Reinstate Monica Mar 11 '15 at 02:46

2 Answers2

2

I don't know about the Standard, but it seems that you can assume all your processors are using the normal IEEE floating point format. In this case, it's pretty easy to determine whether your calculations are correct. The first integer not representable by the 32-bit float format is 16777217 (224+1), so if all your intermediate results are less than that (in absolute value), float will be fine.

The reverse is also true: if any intermediate result is greater than 224 (in absolute value) and odd, float representation will alter it, which is unacceptable for you.

If you are worried specifically about multiplications, look at how the multiplicands are limited. If one is limited by 211, and the other by 213, you will be fine (just barely). If, for example, both are limited by 216, there almost certainly is a problem. To prove it, find a test case that causes their product to exceed 224 and be odd.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

All that you need to know to which limits you may go and still have integer precision should be available to you through the macros defined in <float.h>. There you have the exact description of the floating point types, FLT_RADIX for the radix, FLT_MANT_DIG for the number of the digits, etc.

As you say, whether or not such an approach is efficient will depend on the platform. You should be aware that this is much dependent of the particular processor you'd have, not only the processor family. From one Intel or AMD processor variant to another there could already be sensible differences. So you'd basically benchmark all possibilities and have code that decides on program startup which variant to use.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Thanks for that note on high variation within a family, I didn't know it was that sensitive. With regard to float.h, my only holdup there is that there are guarantees on what can be rounded in then out again unchanged, but if k*m is such an integer, is there any kind of garantee that (float)k*(float)m will produce (float)(k*m)? Also, can FLT_MANT_DIG be taken as a base 2 equivalent of FLT_DIG? I cannot find these guarantees in the standard, and I would need the 1st to have a correctness proof, and the second may be necessary to have a correctness proof for an optimal implementation. – Jack Mar 10 '15 at 08:05
  • 1
    You only have a formal guarantee that the computations within bounds are correct if the macro `__STDC_IEC_559__` is set, which should on all modern archs. `FLT_MANT_DIG` is "better" than `FLT_DIG` because if you compute base `FLT_RADIX` arithmetic is exact as long as the number is representable with the number of `FLT_MANT_DIG` at your disposition. – Jens Gustedt Mar 10 '15 at 10:25
  • I looked into this, and I can verify that this is a way to have a standard verified method for using floats to represent integers, as the IEEE standard seems to force exact results when possible on +,-,x,/,sqrt. Thanks! – Jack Mar 19 '15 at 23:47