Gavin Xu
Gavin Xu

Reputation: 73

Is that good to improve the performance to split the critical section and lock mutex twice?

I am trying to optimize some multi-threads code. I know the way I should focus on is make the critical section smaller, but I meet some code structure and I am not sure what is the best way to improve the performance.

the first question is like this:

mutex.lock();
critical Section A;
func_A(); //func_A() is just a function which will not create confliction.
critical Section B;
mutex.unlock();

func_A() is just a function which will not create confliction. I treat A and B as a whole critical section, If I split the section, let's say, make A and B not in the same critical section like:

mutex.lock();
critical Section A;
mutex.unlock();
func_A(); //func_A() is just a function which will not create confliction.
mutex.lock();
critical Section B;
mutex.unlock();

will this improve my code performance?

Second question is I have some code like:

func1(){
    mutexA.lock();
    critical Section for varibale A;
    mutexB.lock();
    critical Section for varibale B;
    mutexB.unlock();
    critical Section for varibale A;
    mutexA.unlock();
}
func2(){
    if (some condition){
      mutexB.lock();
      critical Section for varibale B;
      mutexB.unlock();
    }
}

Here func1 is a time-consuming function and func2 is not. also, critical Section for variable B is a fast part.

Is that OK for the performance to put one lock inside of another lock? Will it affect the performance too much? Is that OK to just use one mutex for both func1 and func2 rather than 2?

It is really hard to figure out how much these mutexes will cost. I really have no idea for them.

Upvotes: 0

Views: 305

Answers (3)

TonySalimi
TonySalimi

Reputation: 8427

About your first question: If critical sections A and B are time consuming (and independant), then having two separate sections helps two threads to run them concurrently. So, yes, in some cases it may improve the performance.

About your second Q: for light critical sections I always recommend to put them under the same lock. Having less locks helps to avoid deadlocks happening due to programmers mistake as well.

Upvotes: 0

Jonathan Wakely
Jonathan Wakely

Reputation: 171303

will this improve my code performance?

Instead of worrying about performance you should be thinking in terms of correctness. Does it make sense for A and B to happen independently, or should they be a single "atomic" (i.e. indivisible) operation?

If they're separate, independent actions then it might make sense to do:

{
  lock_guard<mutex> l(mutex);
  critical section A
}
func_A();
{
  lock_guard<mutex> l(mutex);
  critical section B
}

But be aware that this will allow your program to do AAAAAABAABBBBABBBB.

If it's important that it does ABABABABABABABABAB then you need to treat them as a single critical section.

So talking about performance without considering how that affects the actual behaviour is misguided. It's impossible to answer your questions about performance without knowing far more detail about the specifics. But performance is probably not what you should be worrying about anyway.

Upvotes: 1

Andriy Tylychko
Andriy Tylychko

Reputation: 16266

First of all, keep it simple, but correct. Then profile. Then, only if required, improve.

Unfortunately I can't provide a more concrete answer here because:

mutex.lock();
critical Section A;
database.loadPetabyteOfData() // just a single line
critical Section B;
mutex.unlock();

Here it makes a perfect sense. If your "few lines which will not create conflict" are fast - don't bother.

Regarding your last example about using a separate mutex for each variable: usually this doesn't make sense too. If you modify a bunch of variables usually together, protect them by the same mutex. Start from a simpler version.

Upvotes: 3

Related Questions