From c4dad0cd83d34379ad1eaa2c0920445a653afad1 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Fri, 24 Nov 2023 21:37:53 -0700 Subject: [PATCH 1/2] Add timer to basic_io example --- cpp/examples/basic_io.cpp | 43 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/cpp/examples/basic_io.cpp b/cpp/examples/basic_io.cpp index abc5fc5110..b7d0dc488b 100644 --- a/cpp/examples/basic_io.cpp +++ b/cpp/examples/basic_io.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -27,6 +28,27 @@ using namespace std; +class Timer { + public: + Timer(const std::string& name) : name(name), start(std::chrono::high_resolution_clock::now()) {} + + ~Timer() + { + auto end = std::chrono::high_resolution_clock::now(); + auto start_ms = + std::chrono::time_point_cast(start).time_since_epoch().count(); + auto end_ms = + std::chrono::time_point_cast(end).time_since_epoch().count(); + + std::cout << "Benchmark " << name << " takes: " << end_ms - start_ms << " microseconds" + << std::endl; + } + + private: + std::string name; + std::chrono::time_point start; +}; + void check(bool condition) { if (!condition) { @@ -82,6 +104,7 @@ int main() check(kvikio::is_host_memory(c_dev) == false); { + Timer timer("Write"); kvikio::FileHandle f("/tmp/test-file", "w"); check(cudaMemcpy(a_dev, a, SIZE, cudaMemcpyHostToDevice) == cudaSuccess); size_t written = f.pwrite(a_dev, SIZE, 0, 1).get(); @@ -90,6 +113,8 @@ int main() cout << "Write: " << written << endl; } { + std::cout << std::endl; + Timer timer("Read"); kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b_dev, SIZE, 0, 1).get(); check(read == SIZE); @@ -102,6 +127,8 @@ int main() } kvikio::defaults::thread_pool_nthreads_reset(16); { + std::cout << std::endl; + Timer timer("Parallel write"); kvikio::FileHandle f("/tmp/test-file", "w"); size_t written = f.pwrite(a_dev, SIZE).get(); check(written == SIZE); @@ -110,9 +137,11 @@ int main() << " threads): " << written << endl; } { + std::cout << std::endl; + Timer timer("Parallel read"); kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b_dev, SIZE, 0).get(); - cout << "Parallel write (" << kvikio::defaults::thread_pool_nthreads() << " threads): " << read + cout << "Parallel read (" << kvikio::defaults::thread_pool_nthreads() << " threads): " << read << endl; check(cudaMemcpy(b, b_dev, SIZE, cudaMemcpyDeviceToHost) == cudaSuccess); for (int i = 0; i < NELEM; ++i) { @@ -120,6 +149,8 @@ int main() } } { + std::cout << std::endl; + Timer timer("Reader buffer registered data"); kvikio::FileHandle f("/tmp/test-file", "r+", kvikio::FileHandle::m644); kvikio::buffer_register(c_dev, SIZE); size_t read = f.pread(c_dev, SIZE).get(); @@ -129,6 +160,8 @@ int main() cout << "Read buffer registered data: " << read << endl; } { + std::cout << std::endl; + Timer timer("Parallel POSIX write"); kvikio::FileHandle f("/tmp/test-file", "w"); size_t written = f.pwrite(a, SIZE).get(); check(written == SIZE); @@ -137,6 +170,8 @@ int main() << " threads): " << written << endl; } { + std::cout << std::endl; + Timer timer("Parallel POSIX read"); kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b, SIZE).get(); check(read == SIZE); @@ -148,6 +183,8 @@ int main() << " threads): " << read << endl; } if (kvikio::is_batch_and_stream_available() && !kvikio::defaults::compat_mode()) { + std::cout << std::endl; + Timer timer("Batch read"); // Here we use the batch API to read "/tmp/test-file" into `b_dev` by // submitting 4 batch operations. constexpr int num_ops_in_batch = 4; @@ -198,6 +235,8 @@ int main() cout << "The batch API isn't available, requires CUDA 12.2+" << endl; } { + std::cout << std::endl; + Timer timer("Async IO by reference"); cout << "Performing async I/O using by-reference arguments" << endl; off_t f_off{0}; off_t d_off{0}; @@ -231,6 +270,8 @@ int main() check(cudaFreeHost((void*)bytes_done_p) == cudaSuccess); } { + std::cout << std::endl; + Timer timer("Async IO by-value"); cout << "Performing async I/O using by-value arguments" << endl; // Let's create a new stream and submit an async write From 20516a24926057a2b139770bedfb00217ad40dff Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 29 Nov 2023 20:47:17 -0700 Subject: [PATCH 2/2] Update Trimer class --- cpp/examples/basic_io.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/cpp/examples/basic_io.cpp b/cpp/examples/basic_io.cpp index b7d0dc488b..24aa2440a4 100644 --- a/cpp/examples/basic_io.cpp +++ b/cpp/examples/basic_io.cpp @@ -30,7 +30,7 @@ using namespace std; class Timer { public: - Timer(const std::string& name) : name(name), start(std::chrono::high_resolution_clock::now()) {} + Timer() : start(std::chrono::high_resolution_clock::now()) {} ~Timer() { @@ -40,12 +40,10 @@ class Timer { auto end_ms = std::chrono::time_point_cast(end).time_since_epoch().count(); - std::cout << "Benchmark " << name << " takes: " << end_ms - start_ms << " microseconds" - << std::endl; + cout << "(" << end_ms - start_ms << " us)" << endl; } private: - std::string name; std::chrono::time_point start; }; @@ -104,7 +102,8 @@ int main() check(kvikio::is_host_memory(c_dev) == false); { - Timer timer("Write"); + cout << endl; + Timer timer; kvikio::FileHandle f("/tmp/test-file", "w"); check(cudaMemcpy(a_dev, a, SIZE, cudaMemcpyHostToDevice) == cudaSuccess); size_t written = f.pwrite(a_dev, SIZE, 0, 1).get(); @@ -114,7 +113,7 @@ int main() } { std::cout << std::endl; - Timer timer("Read"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b_dev, SIZE, 0, 1).get(); check(read == SIZE); @@ -128,7 +127,7 @@ int main() kvikio::defaults::thread_pool_nthreads_reset(16); { std::cout << std::endl; - Timer timer("Parallel write"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "w"); size_t written = f.pwrite(a_dev, SIZE).get(); check(written == SIZE); @@ -138,7 +137,7 @@ int main() } { std::cout << std::endl; - Timer timer("Parallel read"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b_dev, SIZE, 0).get(); cout << "Parallel read (" << kvikio::defaults::thread_pool_nthreads() << " threads): " << read @@ -150,7 +149,7 @@ int main() } { std::cout << std::endl; - Timer timer("Reader buffer registered data"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "r+", kvikio::FileHandle::m644); kvikio::buffer_register(c_dev, SIZE); size_t read = f.pread(c_dev, SIZE).get(); @@ -161,7 +160,7 @@ int main() } { std::cout << std::endl; - Timer timer("Parallel POSIX write"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "w"); size_t written = f.pwrite(a, SIZE).get(); check(written == SIZE); @@ -171,7 +170,7 @@ int main() } { std::cout << std::endl; - Timer timer("Parallel POSIX read"); + Timer timer; kvikio::FileHandle f("/tmp/test-file", "r"); size_t read = f.pread(b, SIZE).get(); check(read == SIZE); @@ -184,7 +183,7 @@ int main() } if (kvikio::is_batch_and_stream_available() && !kvikio::defaults::compat_mode()) { std::cout << std::endl; - Timer timer("Batch read"); + Timer timer; // Here we use the batch API to read "/tmp/test-file" into `b_dev` by // submitting 4 batch operations. constexpr int num_ops_in_batch = 4; @@ -236,7 +235,7 @@ int main() } { std::cout << std::endl; - Timer timer("Async IO by reference"); + Timer timer; cout << "Performing async I/O using by-reference arguments" << endl; off_t f_off{0}; off_t d_off{0}; @@ -271,7 +270,7 @@ int main() } { std::cout << std::endl; - Timer timer("Async IO by-value"); + Timer timer; cout << "Performing async I/O using by-value arguments" << endl; // Let's create a new stream and submit an async write