拆分临界区并两次锁定互斥量是否有助于提高性能?
Is that good to improve the performance to split the critical section and lock mutex twice?
我正在尝试优化一些多线程代码。我知道我应该关注的方法是让关键部分更小,但我遇到了一些代码结构,我不确定提高性能的最佳方法是什么。
第一题是这样的:
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() 只是一个不会产生冲突的函数。
我将 A 和 B 视为一个完整的临界区,如果我拆分该部分,比方说,使 A 和 B 不在同一临界区中,例如:
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();
这会提高我的代码性能吗?
第二个问题是我有一些代码:
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();
}
}
这里func1是一个耗时函数,func2不是。
此外,变量 B 的关键部分是一个快速部分。
将一把锁套在另一把锁的性能上可以吗?会不会太影响性能了?只对 func1 和 func2 使用一个互斥锁而不是两个互斥锁可以吗?
真的很难计算出这些互斥体的成本是多少。我真的不知道他们。
首先,保持简单但正确。然后是简介。然后,仅在需要时进行改进。
很遗憾,我无法在这里提供更具体的答案,因为:
mutex.lock();
critical Section A;
database.loadPetabyteOfData() // just a single line
critical Section B;
mutex.unlock();
这里说的很有道理。如果您的 "few lines which will not create conflict" 很快 - 不要打扰。
关于你最后一个关于为每个变量使用单独的互斥锁的例子:通常这也没有意义。如果您通常一起修改一堆变量,请使用相同的互斥锁保护它们。从更简单的版本开始。
关于你的第一个问题:如果关键部分 A 和 B 是耗时的(并且是独立的),那么拥有两个独立的部分有助于两个线程同时 运行 它们。所以,是的,在某些情况下它可能会提高性能。
关于你的第二个问题:对于轻临界区,我总是建议将它们放在同一个锁下。更少的锁也有助于避免由于程序员的错误而发生的死锁。
will this improve my code performance?
与其担心性能,不如考虑正确性。 A 和 B 独立发生是否有意义,或者它们应该是单个 "atomic"(即不可分割)操作?
如果它们是分开的、独立的动作,那么这样做可能有意义:
{
lock_guard<mutex> l(mutex);
critical section A
}
func_A();
{
lock_guard<mutex> l(mutex);
critical section B
}
但请注意,这将允许您的程序执行 AAAAAABAABBBBABBBB。
如果它执行 ABABABABABABABABAB 很重要,那么您需要将它们视为单个关键部分。
所以在不考虑性能如何影响实际行为的情况下谈论性能是错误的。如果不了解有关细节的更多细节,就不可能回答有关性能的问题。但无论如何,性能可能不是您应该担心的。
我正在尝试优化一些多线程代码。我知道我应该关注的方法是让关键部分更小,但我遇到了一些代码结构,我不确定提高性能的最佳方法是什么。
第一题是这样的:
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() 只是一个不会产生冲突的函数。 我将 A 和 B 视为一个完整的临界区,如果我拆分该部分,比方说,使 A 和 B 不在同一临界区中,例如:
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();
这会提高我的代码性能吗?
第二个问题是我有一些代码:
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();
}
}
这里func1是一个耗时函数,func2不是。 此外,变量 B 的关键部分是一个快速部分。
将一把锁套在另一把锁的性能上可以吗?会不会太影响性能了?只对 func1 和 func2 使用一个互斥锁而不是两个互斥锁可以吗?
真的很难计算出这些互斥体的成本是多少。我真的不知道他们。
首先,保持简单但正确。然后是简介。然后,仅在需要时进行改进。
很遗憾,我无法在这里提供更具体的答案,因为:
mutex.lock();
critical Section A;
database.loadPetabyteOfData() // just a single line
critical Section B;
mutex.unlock();
这里说的很有道理。如果您的 "few lines which will not create conflict" 很快 - 不要打扰。
关于你最后一个关于为每个变量使用单独的互斥锁的例子:通常这也没有意义。如果您通常一起修改一堆变量,请使用相同的互斥锁保护它们。从更简单的版本开始。
关于你的第一个问题:如果关键部分 A 和 B 是耗时的(并且是独立的),那么拥有两个独立的部分有助于两个线程同时 运行 它们。所以,是的,在某些情况下它可能会提高性能。
关于你的第二个问题:对于轻临界区,我总是建议将它们放在同一个锁下。更少的锁也有助于避免由于程序员的错误而发生的死锁。
will this improve my code performance?
与其担心性能,不如考虑正确性。 A 和 B 独立发生是否有意义,或者它们应该是单个 "atomic"(即不可分割)操作?
如果它们是分开的、独立的动作,那么这样做可能有意义:
{
lock_guard<mutex> l(mutex);
critical section A
}
func_A();
{
lock_guard<mutex> l(mutex);
critical section B
}
但请注意,这将允许您的程序执行 AAAAAABAABBBBABBBB。
如果它执行 ABABABABABABABABAB 很重要,那么您需要将它们视为单个关键部分。
所以在不考虑性能如何影响实际行为的情况下谈论性能是错误的。如果不了解有关细节的更多细节,就不可能回答有关性能的问题。但无论如何,性能可能不是您应该担心的。