8

I noticed a big difference in performance of my C program depending on the -fPIC flag. When I use it my program is about 30% slower than without it. I am comparing it with a Lua program which calls a C function (where all the heavy calculation is done). Firstly I created a shared object with the C function, so had to use the -fPIC flag. The performance is very similar to the C code with -fPIC flag. So now I tried to the same without the .so: I called Lua from C:

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    lua_register(L, "my_c_function", my_c_function);
    luaL_dofile(L, "my_lua_program.lua");
    lua_close(L);
    return 0;
}

But here performance is the same regardless if I use the -fPIC flag or not (and the same as the approach with .so). I was expecting some improvement without the -fPIC flag... Any advice on how can I investigate it further? Is the second approach creating position independent code anyway and that's why the performance is similar? Thanks!

More information, as suggested by the comment: I use the -O3 flag, gcc 4.7.2, Ubuntu 12.04.2, x86_64. Yes, I was quite surprised with so big overhead... My program is calculating Mandelbrot fractal. So there are two loops iterating over x and y and the function I have in C is isMandelbrot: it takes the number of iterations and returns bool: belongs to Mandelbrot set or not. I use the shared object with 'require'.

Ola M
  • 1,298
  • 3
  • 12
  • 27
  • 8
    What exact compilation flags are you using? What version of the compiler? What platform and system? What processor architecture? 30% overhead for Position Independent Code seems suspicious (it usually is a few percent). What does your `my_c_function` do? Show its source code if possible... How do you load your shared object? – Basile Starynkevitch Apr 07 '13 at 09:21
  • @Basile Starynkevitch - thank you. I updated the question with more information. Which part of source code would be useful? It's a small program, but I guess I'd need to make is smaller before posting. – Ola M Apr 07 '13 at 10:01
  • Actually your questions made me realise why the second version did not show any improvement: I have left the 'require' statement in the lua code, so still was calling the shared object.... Which does not explain why the -fPIC overhead is so large, but I guess this should be addressed in another question. Thanks again. – Ola M Apr 07 '13 at 10:07
  • If possible, check carefully how is the C code compiled, show the exact compilation command, and the actual code. How often is your `my_c_function` called? How long does it run ? I'm really surprised by your 30% figure. – Basile Starynkevitch Apr 07 '13 at 10:23
  • @Basile Starynkevitch I posted a separate question (as the lua-part of the story is not relevant anymore) with all the details [here](http://stackoverflow.com/questions/15861759/how-much-overhead-can-add-the-fpic-flag). – Ola M Apr 07 '13 at 11:18
  • Remove the Space in `my_c _function` – Joe DF Oct 13 '13 at 14:49
  • If the performance of Lua code is a concern, you may want to look into [LuaJIT](http://luajit.org/). It's *crazy fast*. –  Nov 15 '13 at 20:32
  • When measuring runtime, make sure you run the code to be timed a lot of timss so vagaries average out. Make sure to time only the code you are interested in, overheads (load the program, set it up, ...) can be costly. And before starting into a optimizing chase, measure and think carefully how much work (both bumming now and then debugging, and finally understanding it next month when you need to change it) it will be, and how much you could gain overall. – vonbrand Jan 31 '14 at 22:17

2 Answers2

1

I think the code you are running on is x86. This platform has performance issues with -fPIC, where the location of any imported function requires the local eip to be found. The code to do this adds a small overhead to the function. Unfortunately lua is full of very small functions, and it will increase the relative overhead.

On x64 -fPIC doesn't have this overhead.

mksteve
  • 12,614
  • 3
  • 28
  • 50
-4

Ok first of all, there is almost no difference if you call c program with c program or with lua, but, every time the c program gets created you are making who;e independent program, with all system headers to pop, and then, after its finished doing what is doing, it reports value back. My point is that problem may not be "calling" function but how many and how fast, because there is a lot to do after just calling program.

o3 optimisation flag is not very healthy, so if u did this once u may want also try -Ofast as well, just not use -Os it may just do things worse...

The easiest way to improve performance is just optimising c code and you may want to try optimisation flag during compilation. Here is whole bunch of flags and a lot of documentation on those under GCC compiler. Be aware that not all of them are safe and not all of them are really needed, so analyse your code and choose only those what you need.

Second way of optimisation your code is considered slightly hard. You may want to start a C program while starting lua script and then exchange informations in runtime (parallel) so you dont need to call whole program to show each time you call it

third, hardest way, letting your C code create n threads, where n<=processor logic cores so they can work independently.

also if you dont mind, C/c++ code is good at math things but there are better languages where you can get more performance, like Fortran, APL, Matlab, Haskel, R, or if u are crazy enough and you have good knowledge of mathematical problems - use GPU instead of CPU -> Shader Language, i used them too to some kind of weird stuff, even not close to Graphics but its works for me.

esavier
  • 423
  • 4
  • 13
  • "there is almost no difference if you call c program with c program or with lua" No. A C function called from Lua may need to interact with the Lua stack. There is also interpreter overhead. – Taylor Jan 09 '15 at 22:48
  • "every time the c program gets created you are making whole independent program, with all system headers to pop, and then, after its finished doing what is doing, it reports value back." No. When you call a C function from Lua you are most definitely not creating a separate process. – Taylor Jan 09 '15 at 22:49
  • 1
    if you have already created process yes, this is only about calling function and waiting for result, still earlier or later you need to create "process". Function can not be called from thin air - without system dependent operational stack - you need program or process to hold info about every stuff, then you can call function on this process. Moreover there is no such thing like interpreter overhead - itnerpreter is just calling function and waiting, we are talking about what we need to get result from this function – esavier Jan 10 '15 at 10:12