views:

167

answers:

4

I am testing my java application for any performance bottlenecks. The application uses concurrent.jar for locking purposes.

I have a high computation call which calls lock and unlock functions for its operations. On removing the lock-unlock mechanism from the code, I have seen the performance degradation by multiple folds contrary to my expectations. Among other things observed was increase in CPU consumption which made me feel that the program is running faster but actually it was not.

Q1. What can be the reason for this degradation in performance when we remove locks?

Best Regards !!!

+3  A: 

Profile it. Anything else here will be just a guess and an uninformed one at that.

Using a profiler like YourKit will not only tell you which methods are "hot spots" in terms of CPU time but it will also tell you where threads are spending most of their time BLOCKED or WAITING

Kevin
I have to disagree with the answer here Kevin. I have already profiled my code and does not lends me anywhere. To simplify the things, the code I have running on CPUS (8 cpu box) is CPU intensive process.The hot spots in terms of CPU time are exactly the same for both 1. the code with locks and 2. the code without locks. Obviously, the lock calls are missing in the second but when I say it is a CPU intensive process the performance of code 2 without lock should have been more.Do you have other ideas?Thanks Kevin for Reply
Devil Jin
+1  A: 

Is it still performing correctly? For instance, there was a case in an app server where an unsychronised HashMap caused an occasional infinite loop. It is not to difficult to see how work could simply be repeated.

Tom Hawtin - tackline
I was trying to compare performance of application with and without locks. Ofcourse, when locks were removed, I got "concurrent modification exception" in some threads run.
Devil Jin
Not every bug gets detected. You aren't comparing like with like.
Tom Hawtin - tackline
A: 

The most likely culprit for seeing performance decline and CPU usage increase when you remove shared memory protection is a race condition. Two or more threads could be continually flipping a state flag back and forth on a shared object.

More description of the purpose of your application would help with diagnosis.

Natalia
+1  A: 

This can be quite a usual finding, depending on what you're doing and what you're using as an alternative to Locks.

Essentially, what happens is that constructs such as ReentrantLock have some logic built into them that knows "when to back off" when they realistically can't acquire the lock. This reduces the amount of CPU that's burnt just in the logic of repeatedly trying to acquire the lock, which can happen if you use simpler locking constructs.

As an example, have a look at the graph I've hurriedly put up here. It shows the throughput of threads continually accessing random elements of an array, using different constructs as the locking mechanism. Along the X axis is the number of threads; Y axis is throughput. The blue line is a ReentrantLock; the yellow, green and brown lines use variants of a spinlock. Notice how with low numbers of threads, the spinlock gives heigher throughput as you might expect, but as the number of threads ramps up, the back-off logic of ReentrantLock kicks in, and it ends up doing better, while with high contention, the spinlocks just sit burning CPU.

By the way, this was really a trial run done on a dual-processor machine; I also ran it in the Amazon cloud (effectively an 8-way Xeon) but I've ahem... mislaid the file, but I'll either find it or run the experiment again soon and train and post an update. But you get an essentially similar pattern as I recall.

Update: whether it's in locking code or not, a phenomenon that can happen on some multiprocessor architectures is that as the multiple processors do a high volume of memory accesses, you can end up flooding the memory bus, and in effect the processors slow each other down. (It's a bit like with ethernet-- the more machines you add to the network, the more chance of collisions as they send data.)

Neil Coffey
That's a nice find. But what about removing the locks altogether. Shall this not improved the performance??
Devil Jin
It depends-- if locking was NEEDED for the program to function correctly and you've just removed it arbitrarily, then what is your measurement of "performance" and how valid is it? It's hard to tell without knowing more about what you're doing and the architecture you're running on...
Neil Coffey
See also my update about memory bus flooding: if multiple processors are hammering memory with a high volume of writes, then they can potentially end up having a negative impact on one another. I'm not saying this is necessarily what's happening-- but it's an example of how things are quite complex, and you don't necessarily expect "removing locks" to magically increase performance...
Neil Coffey
'Memory Bus Flooding" never thought of it but I don't disagree with the thing.In my case, I am totally aware that the application I am running is a CPU intensive and not an IO intensive process nor network IO intensive which made me believe that removing locks should have improved performance.Thanks Neil for coming out with wonderful options and I apologize for my delayed reply as i am not aware of notification mechanism here.I agree with your finding that different types of locks give different performance as in your graph
Devil Jin