If I have a (complex) operation that takes a long time for it to finish, for instance, a couple of seconds, my frame rate drops far below the acceptable. How could I still implement it while it is not messing up my frame rate?

It is possible to separate the render thread from the update thread, but it is quiet difficult to make. You'll need a triple-buffer of the render state. For an explanation of the problem and solution check out:

Create separate threads for drawing and logic, if you want improved performance.

But, you can have update() and render() functions, which get called at different times. By doing this, you ensure that these two are separated, and that they do not depend on each other. That's the general direction you want to take, because it makes debugging a lot easier. Plus, once you've done that, creating separate threads for these things will be a piece of cake!

If you were a bit more specific and told us what problems are you having exactly, it would be easier to answer the question.

I agree with the first part. However, I dont think update() and render() methods should be placed in separate threads because there is a lot of dependencies between them and it would affect performance. multithreading is good inside sub-systems, not between them. See gamedev.stackexchange.com/questions/7338/…
–
tigrouAug 6 '12 at 22:19

Note that some engines that exist and ship actually disagree with you. For instance, UE3/UDK.
–
sam hocevarOct 11 '12 at 15:22

My first guess would be multithreading. For example, if you had your logic and render in the main loop, if logic takes a long time, you don't get anything rendered till it is done. With multiple threads, the render can be independant of the logic, and so evedn if the logic is bogged down, stuff still gets rendered, etc.

As per how to calculate it every 1/2 seconds, I am sure whatever libraries you are using contain the simple contraption of some sort of timing devices/timers, etc. Or, in the case the logic is threaded by itself, a sleep might also suffice.

The problem of ensuring the logic is completed by the time it must next be calculated might be tricky, depending on specifically what you are doing. You could: optimize the logic calculations, thread individual part of the logic (though I haven't actually used threads in a real application, so how to seperate but coordinate the logic, I don't know much on). Alternatively, perhaps you can either set a minimum calculation time (say 0.5 seconds) and give it as much time as it needs, or somehow otherwise coordinate the application to the time it takes.