Mar 31, 2021 (data collected Aug 9, 2019)

Concurrent Queue Evaluation

Executive Summary

Initially, BDE supplied two concurrent queue implementations: bdlcc::FixedQueue and bdlcc::Queue. As the name implies, bdlcc::FixedQueue has a fixed sized (specified at construction). bdlcc::Queue grows as needed. Both implementations support multiple producers and multiple consumers. By adding constraints upon the number of producers and consumers, and applying lessons learned since the creation of the initial two queues, queues with a cleaner interface and better performance - as measured by a simple micro-benchmark - were created (note that “bounded” is a synonym for “fixed” with regard to the queue’s capacity):

While a micro-benchmark is never as good an evaluation as a test using production code with real data, the micro-benchmark does demonstrate there exists a usage scenario where these new queue implementations outperform the old implementations. As such, these new queues are valuable additions to the BDE libraries. Furthermore, using the most constrained of the new queues applicable to your problem (e.g., using bdlcc::SingleProducerQueue for a problem with one producer that must never be blocked) is always recommended (if you find a usage scenario where the appropriate new queue significantly underperforms another queue, please contact BDE).

Benchmark

The results presented are based upon throughput measurements, as per bslmt::ThroughputBenchmark, for a simple micro-benchmark where there are a specified number of producer threads that push an element and then perform a specified amount of busy-waiting, and a specified number of consumer threads that pop an element and then perform a specified amount of busy-waiting. Each reported result is the median result of 101 trials of the micro-benchmark, with each trial having a ten millisecond execution time. The parameters of a scenario are:

Abbreviation

Description

Values

PUSH BUSY

number of (arbitrary) work units a producer performs after a push

20, 100, 500, 1000, 5000

POP BUSY

number of (arbitrary) work units a consumer performs after a pop

20, 100, 500, 1000, 5000

#PUSH

number of producer threads

1, 2, 4, 8, 16

#POP

number of consumer threads

1, 2, 4, 8, 16

INIT CAP

queue initial capacity

64, 512, 4096

OS

platform

LINUX, WIN

The values for PUSH BUSY and POP BUSY are measured in an arbitrary unit of work, where each unit of work consists of one 64-bit integer multiplication and a modulus.

Selecting a Result Table

A table is presented to guide the selection of an implementation in a specific situation. The most common situations are formed by the cross product of three constraints: single or multiple producer threads, single or multiple consumer threads, and whether the queue’s size is unbounded, bounded, or either.

In general, with regard to single versus multiple threads, selecting the most constrained queue (e.g., single over multiple producer threads) will result in better performance. However, the constraint must then be met by the usage of the queue. For instance, to use a single producer queue, at most one thread may be using the queue at any given time (e.g., there is only one thread that will use the push methods).

Frequently there are constraints on the size of the queue. For instance, the queue must be unbounded to ensure push operations never block. Or, the queue has a maximum amount of memory that may be used and must therefore be a bounded implementation. Unfortunately, the relative performance of bounded versus unbounded queues can be complicated so choosing a queue in the absence of a constraint may be difficult; the result tables where the queue size is “either” will hopefully help.

Result Table Format

The result tables are information dense and hence provide succinct support for the recommendation of a particular implementation.

A table is comprised of two sections. The title section has three lines: what is being presented, the row and column parameters, and the data filters. The results section is a grid of scenario outcomes represented as a color-coded numeric value.

The first title line details what is being presented, and is always “% Throughput rel. Best”. The presented numeric results are the throughput percentage of the indicate algorithm relative to the best performing implementation. The implementation abbreviations used:

Abbreviation

Implementation

F

bdlcc::FixedQueue

Q

bdlcc::Queue

SP

bdlcc::SingleProducerQueue

SC

bdlcc::SingleConsumerQueue

SPSCB

bdlcc::SingleProducerSingleConsumerBoundedQueue

B

bdlcc::BoundedQueue

The second title line is formatted as “Row Parameter vs. Column Parameter”. For instance, “PUSH BUSY vs. POP BUSY” indicates the row header values are the PUSH BUSY parameter values, and the column header values are the POP BUSY parameter values. The third title line shows the filters for the presented data. For instance, “INIT CAP=64, OS=LINUX” indicates the results were for scenarios where the queue had an initial capacity of 64 elements, and the platform was Linux.

Note that, typically, a number of parameters are not defined within the second and third title lines. The value used for each implementation within a cell is the best result across the unrestricted parameters. For instance, if the title lines are “% Throughput rel. Best”, “PUSH BUSY vs. POP BUSY”, and “INIT CAP=64, OS=LINUX”, the result used for each algorithm in each cell is the one with highest throughput of all scenarios for #PUSH and #POP, divided by the result for the best value and multiplied by 100.

Finally, the result cells are color-coded to indicate the best performing implementation.

Sample Result Table Interpretation

The following table shows the percent throughput relative the best implementation of three queue implementations on the Linux platform for queues having an initial capacity of 64 elements. The three implementations are bdlcc::FixedQueue, bdlcc::BoundedQueue, and bdlcc::Queue. For the PUSH BUSY value 20 (20 units of work are done after each push) and the POP BUSY value 100 (100 units of work are done after each pop), bdlcc::BoundedQueue was the most performant (as indicated by the 100%), the throughput of bdlcc::FixedQueue was 80% that of bdlcc::BoundedQueue, and the throughput of bdlcc::Queue was 50% that of bdlcc::BoundedQueue. This cell is colored to indicate bdlcc::BoundedQueue was the most performant.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
INIT CAP=64, OS=LINUX
100
20
B100
F80
Q50

Multi-Producer, Multi-Consumer, Unbounded

Currently, the only available container for this set of constraints is bdlcc::Queue. As such, the result table is boring.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=LINUX
20 100 500 1000 5000
20
Q100
Q100
Q100
Q100
Q100
100
Q100
Q100
Q100
Q100
Q100
500
Q100
Q100
Q100
Q100
Q100
1000
Q100
Q100
Q100
Q100
Q100
5000
Q100
Q100
Q100
Q100
Q100
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=WIN
20 100 500 1000 5000
20
Q100
Q100
Q100
Q100
Q100
100
Q100
Q100
Q100
Q100
Q100
500
Q100
Q100
Q100
Q100
Q100
1000
Q100
Q100
Q100
Q100
Q100
5000
Q100
Q100
Q100
Q100
Q100
Legend
Q

Multi-Producer, Multi-Consumer, Bounded

The containers available for this set of constraints are bdlcc::FixedQueue and bdlcc::BoundedQueue. bdlcc::BoundedQueue generally outperforms bdlcc::FixedQueue.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=LINUX
20 100 500 1000 5000
20
B100
F73
B100
F65
B100
F91
B100
F75
B100
F99
100
B100
F59
B100
F61
B100
F70
B100
F71
B100
F98
500
B100
F55
B100
F54
B100
F63
B100
F66
B100
F97
1000
B100
F60
B100
F64
B100
F66
B100
F66
B100
F99
5000
F100
B93
F100
B93
B100
F96
B100
F90
F100
B99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=WIN
20 100 500 1000 5000
20
B100
F98
F100
B90
F100
B97
F100
B95
B100
F99
100
B100
F88
F100
B93
F100
B86
B100
F71
B100
F99
500
B100
F75
B100
F63
B100
F98
B100
F89
B100
F99
1000
B100
F70
B100
F70
B100
F68
B100
F76
B100
F98
5000
B100
F97
B100
F96
B100
F95
B100
F93
B100
F99
Legend
B
F

Multi-Producer, Multi-Consumer, Either

The containers available for this set of constraints are bdlcc::Queue, bdlcc::FixedQueue, and bdlcc::BoundedQueue. bdlcc::BoundedQueue generally outperforms the other implementations.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=LINUX
20 100 500 1000 5000
20
B100
F73
Q26
B100
F65
Q34
B100
F91
Q42
B100
F75
Q39
B100
F99
Q98
100
B100
F59
Q22
B100
F61
Q23
B100
F70
Q33
B100
F71
Q35
B100
F98
Q98
500
B100
F55
Q18
B100
F54
Q27
B100
F63
Q31
B100
F66
Q31
B100
F97
Q92
1000
B100
F60
Q24
B100
F64
Q24
B100
F66
Q33
B100
F66
Q43
B100
F99
Q80
5000
F100
B93
Q48
F100
B93
Q47
B100
F96
Q47
B100
F90
Q44
F100
B99
Q79
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
OS=WIN
20 100 500 1000 5000
20
B100
F98
Q54
F100
B90
Q50
F100
B97
Q85
F100
B95
Q60
Q100
B99
F99
100
B100
F88
Q50
F100
B93
Q44
F100
B86
Q61
B100
Q75
F71
Q100
B99
F99
500
B100
Q77
F75
B100
Q74
F63
B100
F98
Q73
B100
F89
Q86
B100
F99
Q98
1000
B100
Q73
F70
B100
F70
Q69
B100
F68
Q68
B100
Q77
F76
B100
Q98
F98
5000
B100
F97
Q82
B100
F96
Q82
B100
F95
Q81
B100
F93
Q79
B100
F99
Q96
Legend
B
F
Q

Single-Producer, Multi-Consumer, Unbounded

The containers available for this set of constraints are bdlcc::Queue and bdlcc::SingleProducerQueue. bdlcc::SingleProducerQueue either outperforms bdlcc::Queue or is a very close competitor (i.e., losing by only 1% of throughput).

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=LINUX
20 100 500 1000 5000
20
SP100
Q44
SP100
Q46
SP100
Q33
SP100
Q16
SP100
Q15
100
SP100
Q71
SP100
Q60
SP100
Q44
SP100
Q66
SP100
Q65
500
SP100
Q93
SP100
Q92
SP100
Q90
SP100
Q83
SP100
Q96
1000
Q100
SP99
Q100
SP99
SP100
Q98
SP100
Q97
SP100
Q98
5000
Q100
SP99
Q100
SP99
Q100
SP99
Q100
SP99
SP100
Q99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=WIN
20 100 500 1000 5000
20
SP100
Q70
SP100
Q60
SP100
Q61
SP100
Q44
SP100
Q21
100
Q100
SP80
Q100
SP95
SP100
Q93
SP100
Q96
SP100
Q67
500
Q100
SP98
SP100
Q94
SP100
Q99
Q100
SP94
SP100
Q99
1000
Q100
SP99
Q100
SP99
Q100
SP99
SP100
Q99
Q100
SP99
5000
Q100
SP99
Q100
SP99
Q100
SP99
Q100
SP99
Q100
SP99
Legend
Q
SP

Single-Producer, Multi-Consumer, Bounded

The containers available for this set of constraints are bdlcc::FixedQueue and bdlcc::BoundedQueue. The results indicate that bdlcc::FixedQueue outperforms bdlcc::BoundedQueue or is a close competitor. Arguably, what the results really show is the need for a special implementation for this constraint set.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=LINUX
20 100 500 1000 5000
20
F100
B66
F100
B77
F100
B59
F100
B97
B100
F99
100
F100
B76
F100
B86
B100
F65
F100
B98
B100
F98
500
F100
B93
F100
B94
F100
B92
F100
B96
F100
B99
1000
F100
B99
F100
B98
F100
B98
B100
F98
B100
F99
5000
F100
B99
F100
B99
F100
B99
F100
B99
B100
F99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=WIN
20 100 500 1000 5000
20
F100
B59
F100
B82
F100
B97
F100
B88
B100
F99
100
B100
F86
B100
F83
B100
F91
B100
F99
B100
F99
500
B100
F97
B100
F97
B100
F98
F100
B97
B100
F99
1000
B100
F99
B100
F99
B100
F99
F100
B99
B100
F99
5000
B100
F99
B100
F99
B100
F99
B100
F99
B100
F99
Legend
B
F

Single-Producer, Multi-Consumer, Either

The containers available for this set of constraints are bdlcc::Queue, bdlcc::SingleProducerQueue, bdlcc::FixedQueue and bdlcc::BoundedQueue. bdlcc::SingleProducerQueue is generally the best choice at the moment. Hopefully, a single-producer, multi-consumer, bounded implementation will simplify the results in the future.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=LINUX
20 100 500 1000 5000
20
F100
SP81
B66
SP100
F89
B69
SP100
F73
B43
SP100
F36
B35
SP100
B16
F15
100
F100
SP89
B76
F100
SP90
B86
SP100
B91
F60
SP100
F72
B71
SP100
B66
F65
500
F100
SP95
B93
F100
SP95
B94
F100
SP94
B92
SP100
F95
B91
SP100
F99
B98
1000
F100
Q99
SP99
F100
Q99
B98
F100
SP98
B98
B100
SP99
F98
SP100
B99
F99
5000
F100
Q99
B99
F100
Q99
SP99
F100
Q99
B99
F100
Q99
B99
B100
SP99
F99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, OS=WIN
20 100 500 1000 5000
20
SP100
F95
Q70
SP100
F77
B63
SP100
F72
B70
SP100
F79
B70
SP100
Q21
B21
100
Q100
SP80
B68
Q100
SP95
B84
SP100
Q93
B90
SP100
Q96
B92
SP100
Q67
B67
500
Q100
SP98
B97
SP100
Q94
B92
SP100
Q99
B97
Q100
SP94
F90
SP100
Q99
B99
1000
Q100
SP99
B98
Q100
SP99
B99
Q100
SP99
B99
SP100
Q99
F98
Q100
SP99
B99
5000
Q100
SP99
B99
Q100
SP99
B99
Q100
SP99
B99
Q100
SP99
B99
Q100
SP99
B99
Legend
B
F
Q
SP

Multi-Producer, Single-Consumer, Unbounded

The containers available for this set of constraints are bdlcc::Queue and bdlcc::SingleConsumerQueue. bdlcc::SingleConsumerQueue generally dominates bdlcc::Queue. Expected improvements to bdlcc::SingleConsumerQueue will hopefully make bdlcc::SingleConsumerQueue the best candidate in all of these scenarios.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=LINUX
20 100 500 1000 5000
20
SC100
Q50
SC100
Q43
SC100
Q16
SC100
Q7
SC100
Q5
100
SC100
Q81
SC100
Q65
SC100
Q36
SC100
Q24
SC100
Q16
500
SC100
Q94
SC100
Q87
SC100
Q93
SC100
Q96
SC100
Q74
1000
SC100
Q92
SC100
Q89
SC100
Q98
SC100
Q97
SC100
Q99
5000
SC100
Q98
SC100
Q98
SC100
Q98
SC100
Q99
SC100
Q99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=WIN
20 100 500 1000 5000
20
Q100
SC86
SC100
Q50
SC100
Q14
SC100
Q9
SC100
Q5
100
Q100
SC88
Q100
SC95
SC100
Q40
SC100
Q27
SC100
Q16
500
Q100
SC97
Q100
SC97
SC100
Q99
SC100
Q96
SC100
Q66
1000
Q100
SC97
Q100
SC97
Q100
SC97
Q100
SC98
SC100
Q93
5000
Q100
SC99
Q100
SC96
Q100
SC99
Q100
SC99
Q100
SC99
Legend
Q
SC

Multi-Producer, Single-Consumer, Bounded

The containers available for this set of constraints are bdlcc::FixedQueue and bdlcc::BoundedQueue. The mixed results imply the need for a special implementation for this constraint set.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=LINUX
20 100 500 1000 5000
20
F100
B50
F100
B83
B100
F99
F100
B99
F100
B99
100
F100
B78
F100
B92
F100
B98
F100
B99
F100
B99
500
B100
F98
F100
B96
F100
B99
F100
B99
F100
B99
1000
B100
F99
B100
F97
F100
B98
B100
F99
B100
F99
5000
B100
F98
B100
F98
B100
F98
F100
B99
F100
B99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=WIN
20 100 500 1000 5000
20
F100
B65
F100
B97
B100
F89
B100
F94
F100
B99
100
F100
B86
F100
B91
B100
F93
B100
F95
F100
B98
500
B100
F92
B100
F96
F100
B97
F100
B94
F100
B98
1000
B100
F91
B100
F92
B100
F96
B100
F99
B100
F99
5000
F100
B99
B100
F99
F100
B98
B100
F99
B100
F99
Legend
B
F

Multi-Producer, Single-Consumer, Either

The containers available for this set of constraints are bdlcc::Queue, bdlcc::SingleConsumerQueue, bdlcc::FixedQueue and bdlcc::BoundedQueue. bdlcc::SingleConsumerQueue is generally the best choice at the moment. Hopefully, a multi-producer, single-consumer, bounded implementation will simplify the results in the future.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=LINUX
20 100 500 1000 5000
20
F100
SC70
B50
SC100
F57
B47
SC100
B16
F16
SC100
F7
B7
SC100
F5
B5
100
F100
SC79
B78
F100
B92
SC88
SC100
F37
B37
SC100
F24
B24
SC100
F16
B16
500
B100
F98
SC96
F100
B96
SC95
F100
B99
SC99
F100
SC99
B99
SC100
F74
B74
1000
B100
F99
SC98
SC100
B97
F95
F100
SC99
B98
SC100
B99
F99
SC100
B99
F99
5000
B100
SC99
F98
B100
SC99
F98
B100
SC99
F98
F100
B99
SC99
F100
SC99
B99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#POP=1, OS=WIN
20 100 500 1000 5000
20
F100
Q80
SC70
SC100
Q50
F44
SC100
Q14
B14
SC100
Q9
B9
SC100
F6
B5
100
Q100
F91
SC88
F100
Q96
SC92
SC100
Q40
B39
SC100
Q27
B26
SC100
Q16
F16
500
Q100
SC97
B96
Q100
SC97
B95
F100
B97
SC94
F100
SC97
B94
SC100
F66
Q66
1000
Q100
SC97
B97
Q100
B98
SC97
Q100
B98
SC97
Q100
B99
F99
B100
SC99
F99
5000
Q100
SC99
F97
Q100
B99
F98
F100
Q98
B98
Q100
B99
SC99
B100
F99
Q99
Legend
B
F
Q
SC

Single-Producer, Single-Consumer, Unbounded

The containers available for this set of constraints are bdlcc::Queue, bdlcc::SingleProducerQueue, and bdlcc::SingleConsumerQueue. bdlcc::SingleProducerQueue is generally the best choice at the moment. Hopefully, a single-producer, single-consumer, unbounded implementation will simplify the results in the future.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=LINUX
20 100 500 1000 5000
20
SP100
SC97
Q48
SP100
SC72
Q31
SP100
SC55
Q9
SP100
SC63
Q4
SP100
SC63
Q3
100
SP100
SC87
Q71
SP100
SC91
Q60
SP100
SC86
Q31
SP100
SC90
Q21
SP100
SC91
Q15
500
Q100
SP98
SC98
Q100
SP98
SC98
SP100
SC99
Q93
SC100
SP99
Q96
SP100
SC99
Q74
1000
Q100
SP99
SC99
Q100
SP99
SC98
Q100
SP99
SC98
SC100
SP99
Q97
SP100
SC99
Q98
5000
SP100
Q99
SC99
SP100
Q99
SC99
Q100
SP99
SC99
SP100
Q99
SC99
SC100
SP99
Q99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=WIN
20 100 500 1000 5000
20
SP100
Q70
SC60
SP100
SC70
Q35
SP100
SC73
Q10
SP100
SC74
Q7
SP100
SC74
Q4
100
Q100
SC88
SP87
SP100
Q91
SC87
SP100
SC90
Q36
SP100
SC91
Q25
SP100
SC92
Q15
500
Q100
SP97
SC97
Q100
SP98
SC97
SP100
Q93
SC93
SP100
SC95
Q92
SC100
SP99
Q66
1000
Q100
SP98
SC97
Q100
SP98
SC97
Q100
SP98
SC97
Q100
SP99
SC98
SP100
SC97
Q91
5000
Q100
SP99
SC99
Q100
SP97
SC96
SP100
Q97
SC96
Q100
SP99
SC99
Q100
SP99
SC99
Legend
Q
SC
SP

Single-Producer, Single-Consumer, Bounded

The containers available for this set of constraints are bdlcc::FixedQueue, bdlcc::BoundedQueue, and bdlcc::SingleProducerSingleConsumerBoundedQueue. The results indicate that bdlcc::SingleProducerSingleConsumerBoundedQueue outperforms the other implementations.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=LINUX
20 100 500 1000 5000
20
SPSCB100
F77
B39
F100
SPSCB98
B83
B100
SPSCB99
F99
SPSCB100
F99
B99
F100
B99
SPSCB99
100
F100
SPSCB98
B78
SPSCB100
F88
B82
F100
SPSCB99
B98
F100
SPSCB99
B99
SPSCB100
F99
B99
500
SPSCB100
B98
F98
SPSCB100
F98
B97
SPSCB100
F97
B96
SPSCB100
F97
B96
SPSCB100
F99
B99
1000
F100
B99
SPSCB98
F100
SPSCB99
B98
F100
SPSCB98
B98
SPSCB100
B98
F98
SPSCB100
B99
F98
5000
F100
SPSCB99
B99
F100
SPSCB99
B99
F100
B99
SPSCB99
F100
SPSCB99
B99
F100
SPSCB99
B99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=WIN
20 100 500 1000 5000
20
SPSCB100
F58
B38
SPSCB100
F92
B89
SPSCB100
B98
F87
SPSCB100
B99
F93
F100
B99
SPSCB99
100
F100
SPSCB97
B86
SPSCB100
F86
B78
SPSCB100
B98
F92
SPSCB100
B97
F93
SPSCB100
F99
B98
500
SPSCB100
B97
F82
SPSCB100
B97
F86
SPSCB100
F96
B94
SPSCB100
F97
B91
F100
SPSCB99
B98
1000
SPSCB100
B99
F87
B100
SPSCB99
F86
B100
SPSCB99
F90
SPSCB100
B98
F98
SPSCB100
B98
F97
5000
SPSCB100
F97
B97
B100
F99
SPSCB97
SPSCB100
F99
B97
B100
SPSCB99
F99
SPSCB100
B99
F99
Legend
B
F
SPSCB

Single-Producer, Single-Consumer, Either

The containers available for this set of constraints are bdlcc::Queue, bdlcc::SingleProducerQueue, bdlcc::SingleConsumerQueue, bdlcc::FixedQueue, bdlcc::BoundedQueue, and bdlcc::SingleProducerSingleConsumerBoundedQueue. The results indicate that the selection of an implementation is very sensitive to the scenario.

% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=LINUX
20 100 500 1000 5000
20
SPSCB100
F77
SP56
SP100
SC72
F41
SP100
SC55
B9
SP100
SC63
SPSCB4
SP100
SC63
F3
100
F100
SPSCB98
SP90
SPSCB100
F88
SP86
SP100
SC86
F32
SP100
SC90
F22
SP100
SC91
SPSCB15
500
Q100
SPSCB99
SP98
Q100
SPSCB99
SP98
SPSCB100
F97
B96
SPSCB100
F97
SC97
SP100
SC99
SPSCB74
1000
F100
B99
Q99
F100
Q99
SPSCB99
Q100
F99
SP99
SPSCB100
SC98
B98
SPSCB100
SP99
SC99
5000
F100
SPSCB99
SP99
F100
SP99
Q99
Q100
F99
B99
F100
SP99
SPSCB99
F100
SPSCB99
SC99
% Throughput rel. Best
PUSH BUSY vs. POP BUSY
#PUSH=1, #POP=1, OS=WIN
20 100 500 1000 5000
20
SPSCB100
SP67
F58
SP100
SC70
Q35
SP100
SC73
SPSCB10
SP100
SC74
Q7
SP100
SC74
F4
100
Q100
F91
SC88
SPSCB100
SP91
F86
SP100
SC90
SPSCB36
SP100
SC91
Q25
SP100
SC92
SPSCB15
500
Q100
SPSCB98
SP97
Q100
SP98
SC97
SPSCB100
SP97
F96
SPSCB100
SP99
F97
SC100
SP99
F66
1000
Q100
SPSCB98
SP98
Q100
B98
SP98
Q100
B98
SPSCB98
SPSCB100
Q98
SP98
SP100
SPSCB99
B98
5000
SPSCB100
Q99
SP99
Q100
B99
F98
SP100
SPSCB99
F99
Q100
SP99
B99
SPSCB100
B99
F99
Legend
B
F
Q
SC
SP
SPSCB

Conclusion

The selection of a queue should always be based upon benchmarking the specific problem; the results presented here are for an unrelated micro-benchmark. As such, the results presented here should be viewed as a starting point to help with the selection process. bdlcc::BoundedQueue is a general replacement candidate for bdlcc::FixedQueue and is a reasonable selection for most problems when the problems allows for a bounded queue. When the problem is bounded and has a single producer and a single consumer, bdlcc::SingleProducerSingleConsumerBoundedQueue should always be a candidate implementation for the problem. For unbounded problems that can be solved using a single producer, bdlcc::SingleProducerQueue should always be a candidate implementation for the problem. Finally, for unbounded problems when a single producer is not a valid constraint, but a single consumer is a valid constraint, consider bdlcc::SingleConsumerQueue.

Extensive Results

An extensive set of result tables is provided in Extensive Results.