我正在arm imx27板上对Windows和Linux进行性能评估。代码已经为CE编写,并测量了执行不同内核调用所需的时间,例如使用OS原语(如互斥和信号量)、打开和关闭文件以及网络。
在我将这个应用程序移植到Linux (线程)的过程中,我偶然发现了一个我无法解释的问题。几乎所有的测试都显示性能从5倍提高到10倍,但不是我的版本的win32事件 (SetEvent和WaitForSingleObject),CE实际上“赢了”这个测试。
为了模拟我使用p线程条件变量的行为(我知道我的实现没有完全模拟CE版本,但它已经足够评估了)。
测试代码使用两个使用事件的“乒乓”线程。
Windows代码:
线程1: (我测量的线程)
HANDLE hEvt1, hEvt2;
hEvt1 = CreateEvent(NULL, FALSE, FALSE, TEXT("MyLocEvt1"));
hEvt2 = CreateEvent(NULL, FALSE, FALSE, TEXT("MyLocEvt2"));
ResetEvent(hEvt1);
ResetEvent(hEvt2);
for (i = 0; i < 10000; i++)
{
SetEvent (hEvt1);
WaitForSingleObject(hEvt2, INFINITE);
} 线程2: (只是“响应”)
while (1)
{
WaitForSingleObject(hEvt1, INFINITE);
SetEvent(hEvt2);
}Linux代码:
线程1: (我测量的线程)
struct event_flag *event1, *event2;
event1 = eventflag_create();
event2 = eventflag_create();
for (i = 0; i < 10000; i++)
{
eventflag_set(event1);
eventflag_wait(event2);
}线程2: (只是“响应”)
while (1)
{
eventflag_wait(event1);
eventflag_set(event2);
}我对eventflag_*的实现
struct event_flag* eventflag_create()
{
struct event_flag* ev;
ev = (struct event_flag*) malloc(sizeof(struct event_flag));
pthread_mutex_init(&ev->mutex, NULL);
pthread_cond_init(&ev->condition, NULL);
ev->flag = 0;
return ev;
}
void eventflag_wait(struct event_flag* ev)
{
pthread_mutex_lock(&ev->mutex);
while (!ev->flag)
pthread_cond_wait(&ev->condition, &ev->mutex);
ev->flag = 0;
pthread_mutex_unlock(&ev->mutex);
}
void eventflag_set(struct event_flag* ev)
{
pthread_mutex_lock(&ev->mutex);
ev->flag = 1;
pthread_cond_signal(&ev->condition);
pthread_mutex_unlock(&ev->mutex);
}和struct
struct event_flag
{
pthread_mutex_t mutex;
pthread_cond_t condition;
unsigned int flag;
};问题:
发布于 2012-01-16 22:56:01
请注意,在调用pthread_cond_signal()时不需要持有互斥对象,因此您可以通过在发出条件信号之前释放互斥对象来提高条件变量'event‘实现的性能:
void eventflag_set(struct event_flag* ev)
{
pthread_mutex_lock(&ev->mutex);
ev->flag = 1;
pthread_mutex_unlock(&ev->mutex);
pthread_cond_signal(&ev->condition);
}这可能会防止唤醒的线程立即阻塞互斥体。
发布于 2013-03-13 19:28:08
只有当您有能力错过事件时,这种类型的实现才能工作。我只是测试了一下,遇到了很多死锁。造成这种情况的主要原因是条件变量只唤醒一个已经在等待的线程。以前发出的信号丢失了。
如果条件已经发出信号,则没有计数器与允许等待线程简单地继续的条件相关联。Windows事件支持这种类型的使用。
我想不出比使用信号量( POSIX版本非常容易使用)更好的解决方案,该信号量初始化为零,set()使用sem_post(),wait()使用sem_wait()。您肯定会想到一种使用sem_getvalue()将信号量计数最多达到1的方法。
尽管如此,我不知道POSIX信号量是否只是Linux信号量的一个整洁接口,或者性能损失是什么。
https://stackoverflow.com/questions/8883512
复制相似问题