If I make my own math header with similar functions as math.h, can I possibly make it as fast as the implementations of math.h, or does math.h use special hardware or something?

Recommended Answers

All 10 Replies

math.h is a library. So you would have to make your own library and just use that name. It is possible to make it faster, depending on what you use, but math.h and cmath has square roots, order of operations,some trig and calculus I think.

My question was whether the library itself uses some special technique to do the calculations faster (asm on some special chip or something)

Are you talking about whether or not the library use an algorithm that optimized its performance for all their functions?

To correct a confusion: math.h is a header. A library (that is, implementation) is libm.so in unix world, and something similar in windows.

You may inspect the source code of libm by looking at the netlib e.g. (which is pretty standard implementation). Maybe you will figure out how to optimize them. Notice however that such code primarilly targets microcontrollers; decent workstation processors all have hardware accelerated math.

Most "special" math functions (like trigo., sqrt and exp/log) translate directly into a single instruction or a few (in assembly), and the performance of those instructions depends on the hardware. Of course, this is if your system has those instructions, most non-microcontrollers have them (unless your PC is more than 20 years old). They used to be much slower than the fundamental arithmetic functions like additions / multiplications, but nowadays, that difference is much smaller.

On micro-controllers, it's a different world, sometimes floating-point arithmetic is not even supported at all, in other cases, floating-point operations are limited to more fundamental arithmetic. In those cases, you do have to resort to hand-rolled implementations (usually a series expansion and some SAS algorithm), or you have to somehow live without it.

When people decide to rewrite some of those math functions on PCs (and they do sometimes), it's usually motivated by needing performance more than robustness. Surely you can appreciate that IEEE-specified math instructions are required to be very safe, precise and predictable over the entire range of possible input values. You certainly pay a price (although fairly small) for that robustness. So, yes, it is possible to have a more efficient implementation of the math functions, but you will most likely have to give away some precision and/or range. In some specific applications (e.g. computer game programming), you need to squeeze every clock-cycle out of the processor, the precision of the calculations is usually not important (only as precise as the eye can see, which is very low precision) and very often, the range is very predictable. In that context, range / overflow / underflow checks can be elided and the series expansion can be very short (and often SAS-like loops can be skipped too), and then, the implementation can achieve better performance, but it is certainly not fit for general use, just for very specific bottleneck sections of code, and it's not worth the effort unless you have pretty much exhausted every other solution to achieve the desired performance. Oh, and at that point, you would probably implement these math functions in assembly too.

Ok, another question then, is there any way to include the math.h header and somehow override the functions so that they can only be called from some implementation class? (basically I need to be able to use sin, cos, tan, etc. as variables and wanted to use a reader-friendly Math.sin() etc. for the math functions and GUI.sin() for the faster but less precise functions.

First, you keep saying "math.h", but this is a C++ forum and you are also referring to writing a class. In C++, the standard header for math functions is "cmath" (as in #include <cmath> ), the "math.h" is only kept for backward compatibility with C and pre-standard C++.

Second, when using the C++ version of math libraries, you have many advantages over the deprecated C version. The first advantage is that C++ has function overloading which allows functions like "sin()" or "exp()" to take different types of values (like float, double, long double) and provide the best implementation for either cases. The second advantage is that all the C++ math functions are wrapped in that "std" namespace, meaning that you can and _should_ invoke functions like so: std::sin() and std::exp() (i.e. the std:: part qualifies the call and asks the compiler to look for the function in the std namespace).

Finally, to solve your problem, you can simply define your versions of the math functions inside another namespace, like fast_math or some other name like that. This way, you would invoke your faster math functions like fast_math::sin() or fast_math::exp() . As so:

namespace fast_math {

float sin(float x);
//..

};

PS: Why on Earth would you want to implement those math functions as member functions of a class? That makes no sense. C++ is not about putting everything into classes (that's Java).

You have a point there... I just need Math.XXX() because im working with somebody that learnt Java before C++. I guess I can just use the cmath functions in my Math class.

Tell the person you are programing with that this is c++ not java. Creating a class that is just holding the math functions is unnecessary. You can just call them when you need the without having the overhead of creating a class.

This might be off-topic but it could be possible to write the stuff in CUDA-C if you have nVidia. I haven't tried it but it is the only thing that might be faster then inline ASM.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.