-2

I am currently writing a program in C which needs to run as fast as possible and am currently looking at improving the speed of some of the calculations performed. I am aware that the slowest operations are multiplication and division, and I have replaced my multiplications/divisions by a power of 2 with left/right shifts.

I was wondering if I could do something similar for multiplication by 6, as it seems that this operation pops up a lot in my program. Regularly it is being multiplied by a number which is 1 or 0, and I feel there should be a good way to speed this up but can't think of any.

Arkleseisure
  • 416
  • 5
  • 19
  • Are you examining your compiler's optimized output and profiling your changes to verify that they're worthwhile? Replacing multiplications by a power of two with bitwise shifts should be performed by pretty much any optimizer out there. – Quentin Dec 23 '22 at 11:31
  • @anastaciu I am multiplying a variable with the value 0 or 1 by the number 6 – Arkleseisure Dec 23 '22 at 11:33
  • @Quentin I have not examined the compiler's output, what would be a good way to do that? – Arkleseisure Dec 23 '22 at 11:35
  • It depends on your specific compiler. For example, GCC has the `-S` flag to output the generated assembly. – Quentin Dec 23 '22 at 11:36
  • 1
    "and I have replaced my multiplications/divisions by a power of 2 with left/right shifts" This is known as pre-mature optimization. Don't do that. The compiler is far more capable than you at doing such optimizations. Instead focus on writing readable and simple code. – Lundin Dec 23 '22 at 11:37
  • @Lundin I was basing my information off this article https://www.geeksforgeeks.org/basic-code-optimizations-in-c/, which seems to think that it will help – Arkleseisure Dec 23 '22 at 11:39
  • 1
    Are you having a real performance issue? Or are you just stuck with the thought of optimizing as much as possible? Furthermore, have you checked that this multiplication really is a bottleneck? – klutt Dec 23 '22 at 11:39
  • @klutt Honestly just trying to optimize as much as possible, and I thought that this might be a way of speeding it up a bit since I noticed that the operation is happening all over the code – Arkleseisure Dec 23 '22 at 11:41
  • @Arkleseisure That site has a nasty reputation. If you want programming advise from naive Indian students, by all means keep using it. If you want programming advise from actual experts who might actually have a clue what they are talking about, then don't. – Lundin Dec 23 '22 at 11:41
  • @Lundin thanks for the advice, I'll avoid it in future – Arkleseisure Dec 23 '22 at 11:43
  • 1
    As for "is there a faster car than my car?". Maybe. Would you care to tell us what car you have? As in, post the code if you want any meaningful answer... It also depends _where_ the code should run. A terrain jeep is so much faster than a Porsche in the forest, but it is far slower on the highway. It is most of the time meaningless to perform manual optimizations unless you 1) have encountered an actual bottleneck 2) have a very specific system in mind and 3) you have fairly in-depth knowledge about that specific system. – Lundin Dec 23 '22 at 11:43
  • 1
    @Arkleseisure It's generarly pointless to optimize before profiling the bottleneck – klutt Dec 23 '22 at 11:44
  • Fair enough, I suppose I'll have a more careful look at the main areas slowing my code down then. – Arkleseisure Dec 23 '22 at 11:47
  • Question: Are you compiling with optimizations enabled? -O2 or perhaps -03? Have you looked at the assembly the compiler produced to see if it didn't already replace it with shifts? Have you profiled your code? – Harith Dec 23 '22 at 11:57
  • @Haris I am compiling with the visual studio compile button, then creating a .so file with gcc -o [loction of lib][file].so -shared -fPIC -O2 [my file].c... I presume the second step optimizes it? – Arkleseisure Dec 23 '22 at 12:11
  • It does enable compiler optimizations, but the trade-off is a less compact executable. – Harith Dec 23 '22 at 12:14
  • arithmetic, especially additions and multiplications by a constant are very rarely a bottleneck. – tstanisl Dec 23 '22 at 12:39
  • @Haris just had a look at the docs, might try out -O3 or -Ofast. Ik it might make it harder to debug but it's also a straightforward way to improve the speed of the program and I'm not too worried about space so it should be fine. – Arkleseisure Dec 23 '22 at 12:59
  • Integer multiplications are as fast as additions ! –  Dec 23 '22 at 22:34
  • @YvesDaoust The answers to the question https://stackoverflow.com/questions/21819682/is-integer-multiplication-really-done-at-the-same-speed-as-addition-on-a-modern seem to think otherwise. – Arkleseisure Dec 24 '22 at 13:04

3 Answers3

5

Trust your compiler. Do not think too much about microoptimizations. They usually have an adverse effect. All versions compile to the same code:

int imul6(int x)
{
    int y = x + x;
    return y+y+y;
}


int imoul6_1(int n)
{
    return ((n << 1) + n) << 1;
}

int imul6_2(int x)
{
    return x+x+x+x+x+x;
}

int imul6_3(int x)
{
    return x*6;
}

https://godbolt.org/z/vMos69PaM

0___________
  • 60,014
  • 4
  • 34
  • 74
1

If the only multipliers are 0 and 1, you can tabulate:

int p[2]= { 0, 6 };

and use p[m];

That's about the only construct that might compete with plain multiplication.

0

You can multiply number n by 6 to get m doing : m = ((n << 1) + n) << 1

lexer31
  • 31
  • 3