• 沒有找到結果。

2.2 The Java virtual machine

2.2.4 WAT, AOT, and JIT compilation

While the popularity of Java rose quickly after its introduction, it also very quickly got a reputation for being slow. As Tyma put it in 1998 The plain truth is: Java is slow. Java isn’t just slow, it’s really slow, surprisingly slow. It is ’you get to watch the buttons being drawn on your toolbar’ slow. [93].

The main reason is all early implementations of the JVM were interpreters. An inter-preter executes a programme by retrieving instructions from memory one at a time, and then executing them. An outline of what a typical interpreter’s main loop looks like is shown in Listing 2.2. For each instruction, the VM needs to (i) retrieve the bytecode at the current programme counter, (ii) increment the programme counter, (iii) jump to the correct case label, (iv) execute the instruction, and (v) loop for the next iteration.

1 while (true) {

2 opcode = bytecode[pc];

3 pc++;

4 switch (opcode) {

5 case ILOAD_0: ...

6 case ILOAD_1: ...

7 ...

8 }

Listing 2.2: Outline of a typical interpreter loop

Since most instructions are very simple, for example simply adding two operands, the relative overhead from these steps is very high. Interpreters spend most of their time on the interpreter loop, and only a fraction of the time on actually executing instructions.

Thus, a common approach to improve JVM performance is to translate the bytecode to the native machine code of the target platform before executing it. Three main approaches exists, which differ in the point at which the bytecode is translated to native code.

Compile time Borrowing the term from Proebsting et al., Way-Ahead-of-Time (WAT) compilers translate to native code during or directly after compiling the Java sources [74].

Some systems first translate to C [23], which is then compiled using normal optimising C compilers.

Regardless of which approach is chosen, the result is a native binary for the target platform, rather than JVM bytecode. The advantage of this approach is that ample time and resources are available at compilation time, so highly optimised code can be produced.

However, the downside is that the resulting code is no longer platform independent or guaranteed to be properly sandboxed.

Load time A second group of compilers translate bytecode to native code at load time.

In these cases the entire application is translated to native code, before it is run. Therefore, they are usually called Ahead-of-Time (AOT) compilers. An example of this approach are early versions of Android’s ART runtime, which translate an app completely, at the moment it is downloaded onto a device (although it since has mixed in JIT techniques as well, discussed below).

This combines the advantage of WAT, being able to spend considerable resources on optimisation, with platform independence and a guaranteed sandbox, since the translation is now fully under control of the device running the application, rather than the device that compiled it. A downside is that the initial translation adds to the time it takes to load or install an application.

Run time Finally, the last group, Just-In-Time (JIT) compilers, incrementally translate the bytecode to native code while the application is running. While an obvious downside is that this may initially slow down the application while it is translating bytecode at run time, a JIT compiler can take advantage of the observed run-time characteristics to make better optimisation decisions, or do more aggressive optimisations that may have to be rolled back if some preconditions no longer hold, for example inlining a virtual method as long as only a single implementation is loaded [45].

Chapter 3

State of the art

This chapter presents the state of the art in Internet of Things and sensor networks relevant to the work in this dissertation. It starts with existing work on programming WSN and IoT networks, and the virtual machines developed for them. Next, it discusses proposed ways to improve sensor node VM performance, and ways to guarantee safety on sensor devices.

3.1 Programming WSN and IoT devices

The challenge of programming IoT devices can be split into two questions:

• How can we build applications at a higher level, coordinating the behaviour of many devices without having to specify the behaviour from each device’s individual per-spective?

• How can we best reprogramme individual nodes safely and efficiently to support these applications?

This dissertation is concerned with the second question, and argues that a virtual ma-chine can be an attractive option in many scenarios. But we will first discuss the higher level question of how to programme WSN/IoT applications and use one of these systems as a motivating example.

Initially, many WSN applications were built directly on top of the hardware or on some minimal operating system such as TinyOS [54]. This results in applications being

programmed from the individual node’s perspective, rather than allowing the developer to express globally what he wants from the sensor network. This makes it hard to reason about the global behaviour, especially as the number of devices and tasks increases.

Therefore, systems have been developed that make it easier for the developer to con-trol the potentially large number of heterogeneous nodes. Some of these are centralised, where the initiative of the application is with a central host, and devices are loaded with a runtime that allows the host to control them. Other systems are more distributed, where the application is split into components that are deployed onto nodes and from there operate autonomously, only to receive further guidance from the host where necessary.

In the first category fall systems like sMap [22], which provides an attractive and flex-ible RESTful interface to a sensor network through which we can discover what sensors are available at a certain node and get or set several configuration properties. Although the authors succeeded in dramatically reducing the footprint, it is still relatively resource intensive. It is also limited in the number of properties it exposes, but the idea could eas-ily be expanded. Similarly TinyDB [61] also makes an entire network of sensor nodes available through a central interface, in this case a SQL-like query language.

ADAE [15], developed at the IT University of Copenhagen, configures the network according to a policy describing the desired data quality, including fall-back options which the system may use when the ideal situation cannot be achieved. ADAE then dynamically reconfigures the network in response to changing conditions such as node failures, unex-pected power drops, or interesting events detected by the network. However, the language used to describe the policy and constraints is hard to use and it is likely a skilled engineer is needed to translate the user’s requirements into the constraint optimisation problem ADAE uses as input.

While in the previous systems applications run on a centralised host and simply control the nodes in the network, in Agilla [28] programmes are more distributed and consist of software agents that can move around in the network autonomously. While this allows some behaviours to be expressed in a natural way, the paradigm is very different from conventional languages, and the assembly-like instruction set based on the Maté VM [52]

discussed below makes it hard to use.

Cornell’s MagnetOS [57], proposes a novel programming model which allows the user to write the application as a single Java application, not explicitly related to individual nodes. The system then automatically partitions the applications into pieces, by default along object boundaries, and places these pieces on nodes in the network in such a way as to minimise energy consumption. However, it requires nodes significantly more powerful than what we expect to find in a typical WSN.

LooCI [43] is a component infrastructure middleware for WSNs with standard support for run-time reconfiguration. The LooCI component model supports dynamic binding and interoperability between different hardware platforms, in their case a typical sensor node based on the ATmega1284P CPU, and the slightly more powerful Sun SPOT, and differ-ent languages, with implemdiffer-entations in C and Java. LooCI defines a list of requiremdiffer-ents for WSN middleware, which includes supporting run-time reconfiguration to respond to changing environmental conditions, supporting heterogeneous sets of hardware, good per-formance, and minimal memory consumption. LooCI currently uses C to programme the smallest devices and Java for the more powerful Sun SPOT. A fast sensor node virtual machine would be a useful addition to allow more flexible and platform independent re-programming of the smallest devices as well.