This is a test scenario to assess the performance of BlockingQueue in the terms of call rates when multiple concurrent writers and readers are present.
| 430 | // This is a test scenario to assess the performance of BlockingQueue in the |
| 431 | // terms of call rates when multiple concurrent writers and readers are present. |
| 432 | TEST_F(BlockingQueueMultiThreadPerfTest, RequestRates) { |
| 433 | SKIP_IF_SLOW_NOT_ALLOWED(); |
| 434 | |
| 435 | vector<size_t> blocking_read_counts(num_blocking_readers_, 0); |
| 436 | for (size_t i = 0; i < num_blocking_readers_; ++i) { |
| 437 | threads_.emplace_back(&BlockingQueueMultiThreadPerfTest::BlockingGetTask, |
| 438 | this, &blocking_read_counts[i]); |
| 439 | } |
| 440 | |
| 441 | vector<size_t> blocking_write_counts(num_blocking_writers_, 0); |
| 442 | for (size_t i = 0; i < num_blocking_writers_; ++i) { |
| 443 | threads_.emplace_back(&BlockingQueueMultiThreadPerfTest::BlockingPutTask, |
| 444 | this, &blocking_write_counts[i]); |
| 445 | } |
| 446 | |
| 447 | vector<size_t> non_blocking_write_counts(num_non_blocking_writers_, 0); |
| 448 | for (size_t i = 0; i < num_non_blocking_writers_; ++i) { |
| 449 | threads_.emplace_back(&BlockingQueueMultiThreadPerfTest::NonBlockingPutTask, |
| 450 | this, &non_blocking_write_counts[i]); |
| 451 | } |
| 452 | |
| 453 | SleepFor(runtime_); |
| 454 | queue_.Shutdown(); |
| 455 | |
| 456 | for_each(threads_.begin(), threads_.end(), [](thread& t) { t.join(); }); |
| 457 | |
| 458 | const auto blocking_reads_num = accumulate( |
| 459 | blocking_read_counts.begin(), blocking_read_counts.end(), 0UL); |
| 460 | const auto blocking_writes_num = accumulate( |
| 461 | blocking_write_counts.begin(), blocking_write_counts.end(), 0UL); |
| 462 | const auto non_blocking_writes_num = accumulate( |
| 463 | non_blocking_write_counts.begin(), non_blocking_write_counts.end(), 0UL); |
| 464 | |
| 465 | LOG(INFO) << "number of successful BlockingGet() calls: " |
| 466 | << blocking_reads_num; |
| 467 | LOG(INFO) << "number of successful BlockingPut() calls: " |
| 468 | << blocking_writes_num; |
| 469 | LOG(INFO) << "number of successful Put() calls: " |
| 470 | << non_blocking_writes_num; |
| 471 | |
| 472 | LOG(INFO) << Substitute( |
| 473 | "BlockingGet() rate: $0 calls/sec", |
| 474 | static_cast<double>(blocking_reads_num) / runtime_.ToSeconds()); |
| 475 | LOG(INFO) << Substitute( |
| 476 | "BlockingPut() rate: $0 calls/sec", |
| 477 | static_cast<double>(blocking_writes_num) / runtime_.ToSeconds()); |
| 478 | LOG(INFO) << Substitute( |
| 479 | "Put() (non-blocking) rate: $0 calls/sec", |
| 480 | static_cast<double>(non_blocking_writes_num) / runtime_.ToSeconds()); |
| 481 | LOG(INFO) << Substitute( |
| 482 | "total Blocking{Get,Put}() rate: $0 calls/sec", |
| 483 | static_cast<double>(blocking_reads_num + blocking_writes_num) / runtime_.ToSeconds()); |
| 484 | LOG(INFO) << Substitute( |
| 485 | "total rate: $0 calls/sec", |
| 486 | static_cast<double>(blocking_reads_num + |
| 487 | blocking_writes_num + |
| 488 | non_blocking_writes_num) / runtime_.ToSeconds()); |
| 489 | } |