@@ -19,37 +19,41 @@ limitations under the License.
1919
2020#include < vector>
2121#include < random>
22+ #include < thread>
23+ #include < chrono>
2224#include < gflags/gflags.h>
2325
2426#include < photon/photon.h>
2527#include < photon/common/alog.h>
2628#include < photon/common/io-alloc.h>
2729#include < photon/fs/localfs.h>
2830#include < photon/thread/thread11.h>
31+ #include < photon/thread/workerpool.h>
2932
3033const static size_t LAST_IO_BOUNDARY = 2 * 1024 * 1024 ;
31- static std::random_device rd;
32- static std::mt19937 gen (rd());
33- static uint64_t qps = 0 ;
34+ static std::atomic<uint64_t > qps{0 };
3435
3536DEFINE_uint64 (io_depth, 128 , " io depth" );
3637DEFINE_string (disk_path, " " , " disk path. For example, /dev/nvme2n1" );
3738DEFINE_uint64 (disk_size, 0 , " disk size. For example, 1000000000000. No need to align. Can be approximate number" );
3839DEFINE_uint64 (io_size, 4096 , " io size" );
3940DEFINE_bool (io_uring, false , " test io_uring or aio" );
41+ DEFINE_bool (use_workpool, false , " dispatch read tasks to multi vCPU by using workpool" );
42+ DEFINE_uint64 (vcpu_num, 4 , " vCPU num of the workpool" );
4043
4144#define ROUND_DOWN (N, S ) ((N) & ~((S) - 1 ))
4245
4346static uint64_t random (uint64_t N) {
44- std::uniform_int_distribution<size_t > distrib (0 , N);
45- return distrib (gen);
47+ static std::random_device rd;
48+ static std::mt19937_64 gen (rd ());
49+ return gen () % N;
4650}
4751
4852static void show_qps_loop () {
4953 while (true ) {
50- photon::thread_sleep ( 1 );
51- LOG_INFO (" QPS: `, BW: ` MB/s" , qps, qps * FLAGS_io_size / 1024 / 1024 );
52- qps = 0 ;
54+ std::this_thread::sleep_for ( std::chrono::seconds ( 1 ) );
55+ LOG_INFO (" QPS: `, BW: ` MB/s" , qps. load () , qps. load () * FLAGS_io_size / 1024 / 1024 );
56+ qps. store ( 0 , std::memory_order_relaxed) ;
5357 }
5458}
5559
@@ -63,7 +67,27 @@ static void infinite_read(const uint64_t max_offset, photon::fs::IFile* src_file
6367 LOG_ERROR (" read fail, count `, offset `, ret `, errno `" , count, offset, ret, ERRNO ());
6468 exit (1 );
6569 }
66- qps++;
70+ qps.fetch_add (1 , std::memory_order_relaxed);
71+ }
72+ }
73+
74+ static void infinite_read_by_work_pool (const uint64_t max_offset, photon::fs::IFile* src_file,
75+ IOAlloc* alloc, photon::WorkPool* work_pool) {
76+ size_t count = FLAGS_io_size;
77+ void * buf = alloc->alloc (count);
78+ while (true ) {
79+ photon::semaphore sem;
80+ work_pool->async_call (new auto ([&] {
81+ uint64_t offset = ROUND_DOWN (random (max_offset), count);
82+ int ret = src_file->pread (buf, FLAGS_io_size, offset);
83+ if (ret != (int ) count) {
84+ LOG_ERROR (" read fail, count `, offset `, ret `, errno `" , count, offset, ret, ERRNO ());
85+ exit (1 );
86+ }
87+ qps.fetch_add (1 , std::memory_order_relaxed);
88+ sem.signal (1 );
89+ }));
90+ sem.wait (1 );
6791 }
6892}
6993
@@ -82,12 +106,15 @@ int main(int argc, char** arg) {
82106 int io_engine = FLAGS_io_uring ? photon::INIT_IO_NONE : photon::INIT_IO_LIBAIO ;
83107 int fs_io_engine = FLAGS_io_uring ? photon::fs::ioengine_iouring : photon::fs::ioengine_libaio;
84108
85- int ret = photon::init (ev_engine, io_engine, photon::PhotonOptions{.libaio_queue_depth = 512 });
109+ photon::PhotonOptions opt;
110+ opt.use_pooled_stack_allocator = true ;
111+ opt.libaio_queue_depth = 512 ;
112+ int ret = photon::init (ev_engine, io_engine, opt);
86113 if (ret != 0 ) {
87114 LOG_ERROR_RETURN (0 , -1 , " init failed" );
88115 }
89116
90- photon::thread_create11 (show_qps_loop);
117+ new std::thread (show_qps_loop);
91118
92119 // Read only open with direct-IO
93120 int flags = O_RDONLY | O_DIRECT ;
@@ -101,8 +128,17 @@ int main(int argc, char** arg) {
101128 AlignedAlloc io_alloc (4096 );
102129 uint64_t max_offset = FLAGS_disk_size - LAST_IO_BOUNDARY ;
103130
104- for (uint64_t i = 0 ; i < FLAGS_io_depth; i++) {
105- photon::thread_create11 (infinite_read, max_offset, file, &io_alloc);
131+ photon::WorkPool* work_pool = nullptr ;
132+ if (FLAGS_use_workpool) {
133+ work_pool = new photon::WorkPool (FLAGS_vcpu_num, ev_engine, io_engine, 0 );
134+ for (uint64_t i = 0 ; i < FLAGS_io_depth; i++) {
135+ photon::thread_create11 (infinite_read_by_work_pool, max_offset, file, &io_alloc, work_pool);
136+ }
137+ } else {
138+ for (uint64_t i = 0 ; i < FLAGS_io_depth; i++) {
139+ photon::thread_create11 (infinite_read, max_offset, file, &io_alloc);
140+ }
106141 }
142+
107143 photon::thread_sleep (-1 );
108144}
0 commit comments