From d52b080081f1ae0e22494a76c17f51dcc99f6dba Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sun, 14 Apr 2019 00:17:04 +0800 Subject: [PATCH] [Java] Avoid unnecessary memory copy and addd a benchmark (#4611) --- java/api/src/main/java/org/ray/api/Ray.java | 1 + .../ray/api/benchmark/MicroBenchmarks.java | 48 +++++++++++++++++++ java/third_party/workspace.bzl | 1 + ...org_ray_runtime_raylet_RayletClientImpl.cc | 19 +++----- src/ray/raylet/task_spec.cc | 4 ++ src/ray/raylet/task_spec.h | 11 +++-- 6 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 java/test/src/main/java/org/ray/api/benchmark/MicroBenchmarks.java diff --git a/java/api/src/main/java/org/ray/api/Ray.java b/java/api/src/main/java/org/ray/api/Ray.java index 769345811..38bc7e933 100644 --- a/java/api/src/main/java/org/ray/api/Ray.java +++ b/java/api/src/main/java/org/ray/api/Ray.java @@ -36,6 +36,7 @@ public final class Ray extends RayCall { public static synchronized void init(RayRuntimeFactory factory) { if (runtime == null) { runtime = factory.createRayRuntime(); + Runtime.getRuntime().addShutdownHook(new Thread(Ray::shutdown)); } } diff --git a/java/test/src/main/java/org/ray/api/benchmark/MicroBenchmarks.java b/java/test/src/main/java/org/ray/api/benchmark/MicroBenchmarks.java new file mode 100644 index 000000000..8a6d90562 --- /dev/null +++ b/java/test/src/main/java/org/ray/api/benchmark/MicroBenchmarks.java @@ -0,0 +1,48 @@ +package org.ray.api.benchmark; + +import org.ray.api.Ray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MicroBenchmarks { + + private static final Logger LOGGER = LoggerFactory.getLogger(MicroBenchmarks.class); + + public static Object simpleFunction() { + return null; + } + + private static void time(Runnable runnable, int numRepeats, String name) { + LOGGER.info("Benchmark \"{}\" started.", name); + final long start = System.nanoTime(); + for (int i = 0; i < numRepeats; i++) { + runnable.run(); + } + final long duration = System.nanoTime() - start; + LOGGER.info( + "Benchmark \"{}\" finished, repeated {} times, total duration {} ms, average duration {} ns.", + name, numRepeats, duration / 1_000_000, duration / numRepeats); + } + + /** + * Benchmark task submission. + * + * Note, this benchmark is supposed to measure the elapased time in Java worker, we should disable + * submitting tasks to raylet in `raylet_client.cc` before running this benchmark. + */ + public static void benchmarkTaskSubmission() { + final int numRepeats = 1_000_000; + Ray.init(); + try { + time(() -> { + Ray.call(MicroBenchmarks::simpleFunction); + }, numRepeats, "task submission"); + } finally { + Ray.shutdown(); + } + } + + public static void main(String[] args) { + benchmarkTaskSubmission(); + } +} diff --git a/java/third_party/workspace.bzl b/java/third_party/workspace.bzl index 193b59924..175cb246a 100644 --- a/java/third_party/workspace.bzl +++ b/java/third_party/workspace.bzl @@ -81,6 +81,7 @@ def list_dependencies(): {"artifact": "com.sun.xml.bind:jaxb-impl:2.3.0", "lang": "java", "sha1": "3a3c6a62719d967175b76b63925f1fb495f11437", "sha256": "edd691fc6ad7c7f3167e1a6833372367bedf6f4f2a4b8230df444a59bb3718b1", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0.jar", "source": {"sha1": "bb0a5a9f4e1116f2bc88fb7d38efd843704b65f8", "sha256": "8627a8a43b0ff84c61c698e3b94e3440e9b30439d0a7085a11677c75eda97ddc", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-impl/2.3.0/jaxb-impl-2.3.0-sources.jar"} , "name": "com_sun_xml_bind_jaxb_impl", "actual": "@com_sun_xml_bind_jaxb_impl//jar", "bind": "jar/com/sun/xml/bind/jaxb_impl"}, {"artifact": "com.typesafe:config:1.3.2", "lang": "java", "sha1": "d6ac0ce079f114adce620f2360c92a70b2cb36dc", "sha256": "6563d1723f3300bf596f41e40bc03e54986108b5c45d0ac34ebc66d48c2e25a3", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/typesafe/config/1.3.2/config-1.3.2.jar", "source": {"sha1": "a22dda7d62b800b297c1c59de90d48992d8119b1", "sha256": "65995abd56d6aa99ee7f46e7cdaaaac2968554b16b26d38bf67e13706a12ca82", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/com/typesafe/config/1.3.2/config-1.3.2-sources.jar"} , "name": "com_typesafe_config", "actual": "@com_typesafe_config//jar", "bind": "jar/com/typesafe/config"}, {"artifact": "commons-beanutils:commons-beanutils:1.9.3", "lang": "java", "sha1": "c845703de334ddc6b4b3cd26835458cb1cba1f3d", "sha256": "c058e39c7c64203d3a448f3adb588cb03d6378ed808485618f26e137f29dae73", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-beanutils/commons-beanutils/1.9.3/commons-beanutils-1.9.3.jar", "source": {"sha1": "9d70af7c5982bd09c33efa97ac98cee6363ba0f0", "sha256": "3315f25f3793c1bb2577b2d956f58f852c7386c73aff4dea450e419a80b00a41", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-beanutils/commons-beanutils/1.9.3/commons-beanutils-1.9.3-sources.jar"} , "name": "commons_beanutils_commons_beanutils", "actual": "@commons_beanutils_commons_beanutils//jar", "bind": "jar/commons_beanutils/commons_beanutils"}, + {"artifact": "commons-collections:commons-collections:3.2.2", "lang": "java", "sha1": "8ad72fe39fa8c91eaaf12aadb21e0c3661fe26d5", "sha256": "eeeae917917144a68a741d4c0dff66aa5c5c5fd85593ff217bced3fc8ca783b8", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar", "source": {"sha1": "78c50ebda5784937ca1615fc0e1d0cb35857d572", "sha256": "a5b5ee16a02edadf7fe637f250217c19878bc6134f15eb55635c48996f6fed1d", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2-sources.jar"} , "name": "commons_collections_commons_collections", "actual": "@commons_collections_commons_collections//jar", "bind": "jar/commons_collections/commons_collections"}, {"artifact": "commons-io:commons-io:2.5", "lang": "java", "sha1": "2852e6e05fbb95076fc091f6d1780f1f8fe35e0f", "sha256": "a10418348d234968600ccb1d988efcbbd08716e1d96936ccc1880e7d22513474", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-io/commons-io/2.5/commons-io-2.5.jar", "source": {"sha1": "0caf033a4a7c37b4a8ff3ea084cba591539b0b69", "sha256": "3b69b518d9a844732e35509b79e499fca63a960ee4301b1c96dc32e87f3f60a1", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-io/commons-io/2.5/commons-io-2.5-sources.jar"} , "name": "commons_io_commons_io", "actual": "@commons_io_commons_io//jar", "bind": "jar/commons_io/commons_io"}, {"artifact": "commons-logging:commons-logging:1.2", "lang": "java", "sha1": "4bfc12adfe4842bf07b657f0369c4cb522955686", "sha256": "daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.jar", "source": {"sha1": "ecf26c7507d67782a3bbd148d170b31dfad001aa", "sha256": "44347acfe5860461728e9cb33251e97345be36f8a0dfd5c5130c172559455f41", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2-sources.jar"} , "name": "commons_logging_commons_logging", "actual": "@commons_logging_commons_logging//jar", "bind": "jar/commons_logging/commons_logging"}, {"artifact": "de.ruedigermoeller:fst:2.47", "lang": "java", "sha1": "281d390ebed24a3621d3053825affc13d0eead8b", "sha256": "8c871febc859cf72dbed1c6c1eebc5600c3d93c3e986feccf4623cc5086098cc", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/de/ruedigermoeller/fst/2.47/fst-2.47.jar", "source": {"sha1": "2e0bb6c02600b3c11c041685a29f6981f3c54c7a", "sha256": "d026fb853b6d5269ec06b9b430488c02c7ac1569fe0233ad785f8bfb7e09688b", "repository": "https://repo.maven.apache.org/maven2/", "url": "https://repo.maven.apache.org/maven2/de/ruedigermoeller/fst/2.47/fst-2.47-sources.jar"} , "name": "de_ruedigermoeller_fst", "actual": "@de_ruedigermoeller_fst//jar", "bind": "jar/de/ruedigermoeller/fst"}, diff --git a/src/ray/raylet/lib/java/org_ray_runtime_raylet_RayletClientImpl.cc b/src/ray/raylet/lib/java/org_ray_runtime_raylet_RayletClientImpl.cc index c0fa6e105..fb7e7b373 100644 --- a/src/ray/raylet/lib/java/org_ray_runtime_raylet_RayletClientImpl.cc +++ b/src/ray/raylet/lib/java/org_ray_runtime_raylet_RayletClientImpl.cc @@ -9,21 +9,14 @@ template class UniqueIdFromJByteArray { public: - const ID &GetId() const { return *id_pointer_; } + const ID &GetId() const { return id; } - UniqueIdFromJByteArray(JNIEnv *env, jbyteArray bytes) : env_(env), bytes_(bytes) { - jbyte *b = reinterpret_cast(env_->GetByteArrayElements(bytes_, nullptr)); - id_pointer_ = reinterpret_cast(b); - } - - ~UniqueIdFromJByteArray() { - env_->ReleaseByteArrayElements(bytes_, reinterpret_cast(id_pointer_), 0); + UniqueIdFromJByteArray(JNIEnv *env, const jbyteArray& bytes) { + env->GetByteArrayRegion(bytes, 0, kUniqueIDSize, reinterpret_cast(id.mutable_data())); } private: - JNIEnv *env_; - jbyteArray bytes_; - ID *id_pointer_; + ID id; }; #ifdef __cplusplus @@ -73,8 +66,8 @@ JNIEXPORT void JNICALL Java_org_ray_runtime_raylet_RayletClientImpl_nativeSubmit execution_dependencies.push_back(cursor_id.GetId()); } - auto data = reinterpret_cast(env->GetDirectBufferAddress(taskBuff)) + pos; - ray::raylet::TaskSpecification task_spec(std::string(data, taskSize)); + auto data = reinterpret_cast(env->GetDirectBufferAddress(taskBuff)) + pos; + ray::raylet::TaskSpecification task_spec(data, taskSize); auto status = raylet_client->SubmitTask(execution_dependencies, task_spec); ThrowRayExceptionIfNotOK(env, status); } diff --git a/src/ray/raylet/task_spec.cc b/src/ray/raylet/task_spec.cc index da8bafc60..917dec944 100644 --- a/src/ray/raylet/task_spec.cc +++ b/src/ray/raylet/task_spec.cc @@ -56,6 +56,10 @@ TaskSpecification::TaskSpecification(const std::string &string) { AssignSpecification(reinterpret_cast(string.data()), string.size()); } +TaskSpecification::TaskSpecification(const uint8_t *spec, size_t spec_size) { + AssignSpecification(spec, spec_size); +} + TaskSpecification::TaskSpecification( const DriverID &driver_id, const TaskID &parent_task_id, int64_t parent_counter, const std::vector> &task_arguments, int64_t num_returns, diff --git a/src/ray/raylet/task_spec.h b/src/ray/raylet/task_spec.h index baa6165c9..86bf35d00 100644 --- a/src/ray/raylet/task_spec.h +++ b/src/ray/raylet/task_spec.h @@ -140,12 +140,17 @@ class TaskSpecification { const std::unordered_map &required_placement_resources, const Language &language, const std::vector &function_descriptor); - /// Deserialize a task specification from a flatbuffer's string data. + /// Deserialize a task specification from a string. /// - /// \param string The string data for a serialized task specification - /// flatbuffer. + /// \param string The string data for a serialized task specification flatbuffers. TaskSpecification(const std::string &string); + /// Deserialize a task specification from raw byte array. + /// + /// \param spec Raw byte array for a serialized task specification flatbuffer. + /// \param spec_size Size of the byte array. + TaskSpecification(const uint8_t *spec, size_t spec_size); + ~TaskSpecification() {} /// Serialize the TaskSpecification to a flatbuffer.