views:

48

answers:

1
A: 

Why don't you use the IOCP as your queue and post your work items directly to it? That way you get a thread safe queue for free and can completely remove the other queue you have?

This question would then go away ;)

Len Holgate
Actually because I am experimenting with a possibly more efficient way of pushing work items onto the queue so I was trying to avoid signalling the port for each work item.
wb
Fair enough, why not remove the IOCP completely and use a semaphore instead then? OR, keep the IOCP, remove your custom queue and look at `GetQueuedCompletionStatusEx()` to remove multiple completions at once for processing.
Len Holgate
As far as I know IOCP is more efficient and scalable than a semaphore.I only want each worker thread to steal one item of work at once - as it can only run one task/job at a time. The problem is in deciding when to signal a worker threads port in between the time it may be starting to fall asleep.
wb
Indeed it is and it will deal with making sure that your queue is thread safe and efficient. If you only want each worker to take one work item at a time then simply use the IOCP as your queue. I don't understand your comment re 'starting to fall asleep'. The OS will deal with informing the best thread that there's work available if you use an IOCP and post each work item... I assume you've profiled your existing IOCP based queue and have numbers that you can compare with your new way?
Len Holgate
I understand what you mean by using it as the actual queue but doesn't this require a kernel mode transition on queueing items?On the 'falling asleep' bit if you look at the code in my example where I am just trying to use the iocp as an efficient mechanism to wake up a worker thread that is pulling data from a user mode lock free list (That doesn't involve a kernel mode transition per work item).
wb
I expect it does require a kernel mode transition; but then so would setting an event, using a semaphore or posting to the IOCP "only when you need to". The problem with the later is that there will always be a race condition on the "when you need to", especially since you container is lock free. I'd profile it and make sure you're actually getting the gain you think you are.
Len Holgate
With the lockless queue its measurably more efficient by about 10-15% from submitting a large amount of random tasks (This is for a general purpose task system not just for responding to network events etc).Just relying on IOCP isn't bad for a moderate number of tasks that do a fair amount of work but its not as fast as it could be.Perhaps the answer to my original question is some sort of solution that may sometimes accidentally wake up a thread when its not needed - ie an already running thread completes its task and grabs the next work before another thread that was woken up for it.
wb
I guess the question is how efficient is the queue WITH a reasonably reliable wake up system; if you wake too many threads every so often but you're still more efficient then you're still winning.
Len Holgate