OpenCL Actors { Adding Data Parallelism to Actor-based Programming with CAF Raphael Hiesgen∗1, Dominik Charousset1, and Thomas C. Schmidt1 1Hamburg University of Applied Sciences Internet Technologies Group Department Informatik, HAW Hamburg Berliner Tor 7, D-20099 Hamburg, Germany September 25, 2017 Abstract The actor model of computation has been designed for a seamless support of concurrency and dis- tribution. However, it remains unspecific about data parallel program flows, while available processing power of modern many core hardware such as graphics processing units (GPUs) or coprocessors increases the relevance of data parallelism for general-purpose computation. In this work, we introduce OpenCL-enabled actors to the C++ Actor Framework (CAF). This offers a high level interface for accessing any OpenCL device without leaving the actor paradigm. The new type of actor is integrated into the runtime environment of CAF and gives rise to transparent message passing in distributed systems on heterogeneous hardware. Following the actor logic in CAF, OpenCL kernels can be composed while encapsulated in C++ actors, hence operate in a multi-stage fashion on data resident at the GPU. Developers are thus enabled to build complex data parallel programs from primitives without leaving the actor paradigm, nor sacrificing performance. Our evaluations on commodity GPUs, an Nvidia TESLA, and an Intel PHI reveal the expected linear scaling behavior when offloading larger workloads. For sub-second duties, the efficiency of offloading was found to largely differ between devices. Moreover, our findings indicate a negligible overhead over programming with the native OpenCL API. Keywords: Actor Model, C++, GPGPU Computing, OpenCL, Coprocessor 1 Introduction The stagnating clock speed forced CPU manufacturers into steadily increasing the number of cores on commodity hardware to meet the ever-increasing demand for computational power. Still, the number of arXiv:1709.07781v1 [cs.DC] 22 Sep 2017 parallel processing units on a single GPU is higher by orders of magnitudes. This rich source of computing power became available to general purpose applications as GPUs moved away from single purpose pipelines for graphics processing towards compact clusters of data parallel programmable units [36]. Many basic algorithms like sorting and searching, matrix multiplication, or fast Fourier transform have efficient, massively parallel variants. Also, a large variety of complex algorithms can be fully mapped to the data parallel architecture of GPUs with a massive boost in performance. Combined with the widespread availability of general-purpose GPU (GPGPU) devices on desktops, laptops and even mobiles, GPGPU ∗Corresponding author: [email protected] 1 computing has been widely recognized as an important optimization strategy. In addition, accelerating coprocessors that better support code branching established on the market. Since not all tasks can benefit from such specialized devices, developers need to distribute work on the various architectural elements. Managing such a heterogeneous runtime environment inherently increases the complexity. While some loop-based computations can be offloaded to GPUs using OpenACC [10] or recent versions of OpenMP [15] with relatively little programming effort, it has been shown that a consistent task-oriented design exploits the available parallelism more efficiently. Corresponding results achieve better performance [27] while they are also applicable to more complex work loads. However, manually orchestrating tasks between multiple devices is an error-prone and complex task. The actor model of computation describes applications in terms of isolated software entities|actors| that communicate by asynchronous message passing. Actors can be distributed across any number of processors or machines by the runtime system as they are not allowed to share state and thus can always be executed in parallel. The message-based decoupling of software entities further enables actors to run on different devices in a heterogeneous environment. Hence, the actor model can simplify software development by hiding the complexity of heterogeneous and distributed deployments. In this work, we take up our previous contribution [22] about actors programmed with OpenCL| the Open Computing Language standardized by the Khronos Group [41]. We enhance the integration of heterogeneous programming with the C++ Actor Framework [11] by a fully effective encapsulation of OpenCL kernels within C++ actors|the OpenCL actor. OpenCL actors can be transparently used at regular actor programming (e.g., like a library or toolset). They can be composed like standard CAF actors, which leads to a multi-staging of OpenCL kernels. We present indexing as a realistic use case for this elegant programming approach. Furthermore, we thoroughly examine the runtime overhead introduced by our abstraction layer, and justify our integration of heterogeneous hardware to the existing benefits of CAF such as network-transparency, memory-efficiency and high performance. The remainder of this paper is organized as follows. Section 2 introduces the actor model as well as heterogeneous computing in general and OpenCL in particular. Our design goals and their realization are laid out in Section 3. Along these lines, benefits and limitations of our approach are thoroughly discussed. An application use case that is composed of many data parallel primitives is described in Section 4. In Section 5, we evaluate the performances of our work with a focus on overhead and scalability. Finally, Section 6 concludes and gives an outlook to future work. 2 Background and Related Work Before showing design details, we first discuss the actor model of computation, heterogeneous computing in general, and OpenCL. 2.1 The Actor Model Actors are concurrent, isolated entities that interact via message passing. They use unique identifiers to address each other transparently in a distributed system. In reaction to a received message, an actor can, (1) send messages to other actors, (2) spawn new actors and (3) change its own behavior to process future messages differently. These characteristics lead to several advantages. Since actors can only interact via message passing, they never corrupt each others state and thus avoid race conditions by design. Work can be distributed by spawning more actors in a divide and conquer approach. Further, the actor model addresses fault- tolerance in distributed systems by allowing actors to monitor each other. If an actors dies unexpectedly, the runtime system sends a message to each actor monitoring it. This relation can be strengthened through bidirectional monitors called links. By providing network-transparent messaging and fault propagation, the actor model offers a high level of abstraction for application design and development targeted at concurrent and distributed systems. 2 Hewitt et al. [21] proposed the actor model in 1973 as part of their work on artificial intelligence. Later, Agha formalized the model in his dissertation [2] and introduced mailboxing for processing actor messages. He created the foundation of an open, external communication [3]. At the same time, Armstrong took a more practical approach by developing Erlang [6]. Erlang is a concurrent, dynamically typed programming language developed for programming large- scale, fault-tolerant systems [5]. Although Erlang was not build with the actor model in mind, it satisfies its characteristics. New actors, called processes in Erlang, are created by a function called spawn. Their communication is based on asynchronous message passing. Processes use pattern matching to identify incoming messages. To combine the benefits of a high level of abstraction and native program execution, we have developed the C++ Actor Framework (CAF) [11]. Actors are implemented as sub-thread entities and run in a cooperative scheduler using work-stealing. As a result, the creation and destruction of actors is a lightweight operation. Uncooperative actors that require access to blocking function calls can be bound to separate threads by the programmer to avoid starvation. Furthermore, CAF includes a runtime inspection tool to help debugging distributed actor systems. In CAF, actors are created using the function spawn. It creates actors from either functions or classes and returns a network-transparent actor handle. Communication is based on message passing, using send or request. The latter function expects a response and allows setting a one-shot handler specifically for the response message. This can be done in two ways: either the actor maintains its normal behavior while awaiting the response or it suspends its behavior until the response is received. CAF offers dynamically as well as statically typed actors. While the dynamic approach is closer to the original actor model, the static approach allows programmers to define a message passing interface which is checked by the compiler for both incoming and outgoing messages. Messages are buffered at the receiver in order of arrival before they are processed. The behavior of an actor specifies its response to messages it receives. CAF uses partial functions as message handlers, which are implemented using an internal domain-specific language (DSL) for pattern matching. Messages that cannot be matched stay in the buffer until they are discarded manually or handled by another behavior. The behavior can be changed dynamically during message processing. In previous work [12], we compared CAF to other
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages28 Page
-
File Size-