|
Frequently Asked Questions
Programmers
-
Q. How does it work?
-
Q. How do
I use reflective memory?
-
Q. What kind
of data can I keep in reflective memory?
-
Q. Can I share data in reflective memory between different application
processes on the same system?
-
Q. Do I need to serialize access to shared data in reflective memory?
-
Q.
How do I ensure that remote memory is updated consistently?
-
Q. What
happens when a new node joins an existing Ring?
A. AmirusMM™ is a peer-to-peer system
which ‘reflects’ memory to all nodes configured in a cooperative network.
In a typical configuration, the memory defined as part of the reflective memory
area is set up as Read-Only, as far a the operating system is concerned. When an application writes to this memory
location, a fault exception is generated which triggers code to store the change
in a transmit FIFO before actually writing the data into memory. The
transmit FIFO is drained when the node is given “permission to talk” by other
nodes in the network. As other nodes talk on the network, the local node
updates its copy of the local memory.
A. You use it in the same way as you would use ordinary
memory, but first you must connect to it using a special subroutine call. This
subroutine returns a pointer to the memory as it is mapped, just as malloc
would return a memory address when allocating ordinary memory. How much memory
gets mapped is determined by the configuration, which is established before any
applications that use the memory are started. The size of the memory area
is returned in the map call.
Memory regions are referred to by name, and you can
determine their specific characteristics by a subroutine call if you are
interested,
If you are using MATLAB, an optional interface hides these details, allowing you
to read and write scalars and arrays through MATLAB class objects. If you are
using Visual Basic .NET, there is an optional interface to simplify data
management too, since VB.NET gives you limited options to arrange data at
specific memory locations.
A. You can keep any kind of information you like in AmirusMM™
memory except program stacks. Any instruction which
reads or writes data into memory can be used, but implicit references to memory
through the stack pointer (SP) are forbidden.
If you execute an instruction which attempts an
implicit write (PUSH, CALL, ENTER, etc., with the processor stack pointer (SP)
set to an AmirusMM™ address), your thread will generate a write
protection violation. If this exception is not caught, the thread will exit.
A. Yes. AmirusMM shared memory can be used as ordinary
shared memory between different applications. Each application may map the
memory into different addresses in its own address space, but it is the same
memory.
But unlike ordinary shared memory, applications sharing Amirus memory can
request that they be notified when another process writes to memory. A
subroutine call requests this notification on a per-process basis.
A. If you are writing to the same memory from different applications or
machines, yes. The usual methods are needed to make sure
that different threads don’t fall over themselves when writing to mirror
memory on a local system. If you need to lock memory throughout the system
(including memory on other nodes too), you must use the global locking API in
addition to the local mechanisms. If you don't do this, or don't rigorously
enforce a design where nodes talk only to their own areas of memory, memory on
different nodes can become inconsistent.
The API provides for 32 global locks, numbered 0 through
31. You can request access to a lock at either "Shared" or "Exclusive" level.
"Shared" locks are granted even if other nodes also have the lock "Shared";
however, they are not granted if another node has the lock "Exclusive".
"Exclusive" locks are granted only if no other node has the lock.
Typically, you use a "Shared" lock if you are attempting read-only access and
want to guarantee that no other node is writing into the memory area. Other
nodes just reading (who will also have the "Shared" lock) can proceed in
parallel. You use the "Exclusive" lock if you want read-write access to the area
-- you won't be granted the lock until all readers release their "Shared" lock.
The locking facility is "advisory" -- you must ensure that all processes
accessing the memory area use the same convention for memory access. There is
nothing to prevent a process writing to any memory location if it has the
ability to map the shared memory in use. Establishing a convention that you must
have (for example) Lock 13 to access structure _fred is all that is required to
ensure coherent access. This is similar to locking semantics found on some
versions of Unix.
Conflicting lock requests are granted in round-robin order, which ensures that
each node has an equal share of lock access. Locks owned by a node that fails
automatically become available again for other nodes to request. There is no
deadlock detection available at system level; however, lock requests can have
associated timeouts, allowing you to implement your own deadlock resolution
protocol if you so wish.
A. One way is to use "Synchronized" memory. Synchronized memory guarantees that changes you make
to local memory are propagated to every node before the writing thread on the
local node executes the next instruction. This adds a significant time penalty
to your local process, as it is suspended until all other nodes have been
updated.
The AmirusMM™ system guarantees that the order of writes on
one system is the same as the perceived order of reads on each and every remote
system. This is true even if the remote systems have multiple processors. .
Unless you are using "Synchronized" memory, there is no guarantee that the
remote machines will be updated at the same time - you could (and generally will
be) proceeding with the next instruction in sequence while the other machines
are still seeing the old data.
Note that you can maintain consistency through enforcing a system-wide policy of
requiring shared memory areas to be accessed through the lock facility. This is
generally a better mechanism to use, since it provides for enhanced parallelism.
"Synchronized" memory is conceptually closer to synchronization mechanisms
available to hardware reflective memory users, and is primarily provided as an
aid for migrating hardware RM applications.
A. When a new node joins an existing Ring, several complex operations are
performed to make sure that the memory contents in the joining member are
consistent with those in all other nodes.
First, all active client programs on existing Ring members are stalled at their
next write. This ensures that no more data is written into the pending buffers
for transmission around the Ring. Active client programs which are reading
Mirror Memory, or those not accessing memory at all are unaffected.
Next, all nodes proceed until all data they have in their output FIFO's has been
transmitted to each existing Ring member. The system maintains any locks which
are owned by the existing nodes. As the memory in each Ring member reaches an
internally consistent state, an invitation to join the Ring is issued to the
node (or nodes) which plan to join.
The existing nodes then transmit -- round robin -- the zero-compressed contents
of their memory areas. Joining nodes take this data and use it to initialize
their memory. Existing nodes monitor each others transmission to check it for
consistency. Inconsistent memory is tagged in the system error log file. Note
that inconsistent memory can arise if incorrect (or non-existent) locking calls
have been made by programs writing into the same memory locations.
Finally, when all memory in the existing nodes have been properly initialized,
any stalled active client programs are released and processing continues.
Nodes leaving the system by design drain all their output FIFO's prior to
leaving the Ring and wait until all other members have seen the data. Any locks
that that node might have been granted are released. A node leaves the system by
design when the controlling server program exits -- typically 10 minutes after
the last client process on that node terminates, although this timeout interval
is configurable. A node also leaves by design if it follows the standard system
shutdown procedure.
Nodes leaving the system because of a network outage or system failure cause a
Ring timeout, which delays data transmission by some 20 milliseconds
(configurable). During the recovery, the remaining nodes ensure overall
consistency by exchanging previously cached packets from the failing node. Any
locks that the failing node might have possessed are granted instead to any
surviving node that is requesting them in round-robin order. In this way, data
consistency is assured in any network configuration and in all possible failure
scenarios, including partial connections (where some machines might become
invisible to some, but not all, others).
|