【发布时间】:2011-02-15 21:08:17
【问题描述】:
我有一个项目,其中我有一个将事件写入缓冲区的单个生产者线程,以及一个从缓冲区获取事件的附加单个消费者线程。我的目标是针对单个双核机器优化这个东西,以实现最大吞吐量。
目前,我正在使用一些简单的无锁环形缓冲区(无锁是可能的,因为我只有一个消费者和一个生产者线程,因此指针仅由单个线程更新)。
#define BUF_SIZE 32768
struct buf_t { volatile int writepos; volatile void * buffer[BUF_SIZE];
volatile int readpos;) };
void produce (buf_t *b, void * e) {
int next = (b->writepos+1) % BUF_SIZE;
while (b->readpos == next); // queue is full. wait
b->buffer[b->writepos] = e; b->writepos = next;
}
void * consume (buf_t *b) {
while (b->readpos == b->writepos); // nothing to consume. wait
int next = (b->readpos+1) % BUF_SIZE;
void * res = b->buffer[b->readpos]; b->readpos = next;
return res;
}
buf_t *alloc () {
buf_t *b = (buf_t *)malloc(sizeof(buf_t));
b->writepos = 0; b->readpos = 0; return b;
}
但是,这个实现还不够快,应该进一步优化。我尝试了不同的BUF_SIZE 值并获得了一些加速。另外,我将writepos 移到buffer 之前和readpos 之后buffer 之后,以确保这两个变量位于不同的缓存行上,这也带来了一定的速度。
我需要的是大约 400 % 的加速。你有什么想法我可以使用填充等来实现这一点吗?
【问题讨论】:
-
“无锁是可能的,因为我只有一个消费者和一个生产者线程” - 如果消费者和生产者线程冲突会发生什么?
-
忙等待中消耗了多少 CPU?
-
忙等待???如果你有忙等待,你不会问如何让它更快。
-
如果我错了,请纠正我,但如果您有多个 CPU,您可能需要在生产和消费之间设置内存屏障。这会减慢您的速度(可能很多),但没有它,消费者可能会在数据写入缓冲区之前看到写入索引移动,并检索无效数据。
-
“单机”是什么意思?线程在一个进程内,通常一个进程在一台且仅一台机器上运行。通常的问题是您有多少个 CPU 内核,因为 MT 错误通常只出现在多核场景中,其中工作实际上是并行完成的,并且存在内存缓存问题。
标签: c performance multithreading caching shared-memory