Wednesday, November 11, 2009

More Implementation Strategy patterns

Shared Queues
This pattern covers the common practice of using a shared queue in concurrent program. The authors talk about the major decisions being a centralized vs decentralized queue and simple protocols vs. more concurrency.

I have implemented a shared queue, where a pool of threads pulled tasks out of a shared queue. Since the accessing the queue represented a fractional amount of the task, it used what the authors call a simple protocol, using a mutex to protect the data structure. It was also centralized, since the application was running on a single system. If the program had spent more time in the dequeue or queueing operations, I may have chose to implement in a way that allowed greater concurrency.

Speculation
I found this pattern rather neat, as I hadn't thought of applying the idea which I was aware of to my software before. Rather than worrying a serialized task must run serially, one can still divide it up, detect if the result is correct, then rerun the parts that are incorrect serially.

It seems to me that problems that could fall under this are not too common as it needs several preconditions. First, the tasks must be long enough to to warrant the overhead and dividing up of speculations. Second, the task must be at least potentially dividable. The example given of parsing HTML was great as the page can be divided up. However, if the each task truly requires a previous task to complete, it will need rerun anyway, unless the result of the previous task can be guessed.

Circuits
This pattern was not what I expected when I read the name. Instead of being about digital circuits, it was really on how to parallelize bitwise operations over large blocks. A help in some contexts, but not one I'd tend to see in my work.

Monday, November 9, 2009

Implementation Strategy Patterns

These patterns cover some of the ones available when implementing algorithms for a parallel program.

Loop Parallelism
This pattern covered some of the techniques available for parallelizing loops, or allowing the loop to be processed concurrently over different bounds. The author first recommends profiling the application to identify what loops are used the most and use those as candidates. If one has a target increase desired, using Amdahl's law shows how much code needs to be improved. This could present a large percentage of the loops.

Task Queue Implementation
Tasks can be used for several different algorithms, such as graph traversal or part of loop parallelism. When implementing this pattern, first a task granularity must be decided upon, as discussed in other patterns. Next, the structure for the queue, centralized or decentralized must be chosen, with pros and cons for either choice.

It was nice to see code examples, although writing them in Python may not be the most universal way to document a pattern, as it is not as popular as c++ or Java. Even with out the examples, the concepts in this pattern were not as complex as others, which would have benefited more from examples.

Graph Partitioning
This pattern covered some of the many different ways a graph may be partitioned. As this is an NP-complete problem, different heuristical approaches were presented. I have not been in a position where I needed to do this, but having it documented may be useful for others in the academic or scientific domain.

PRES

PRES is a neat tool that helps developers reproduce concurrency bugs found in the field. Some tools try to search every path, but can take many replays (1000+) before being able to reproduce the problem. This is due to the many sources of nondeterminism in a multiprocessor system. Threads can be interleaved in any order. The other approach is to capture run time data when the system is deployed to reproduce any problem, but this comes at a high cost of performance, sometimes slowing down the system 10X.

PRES takes a middle ground of recording some of the run time data, such as the order functions are called. When a developer needs to reproduce a bug, he gathers this data and PRES uses it to limit the number of replays required in order to reproduce a bug. It guides the replay system automatically to not go down paths that did not happen in the field.

I thought it also made a wise choice to start with the possible race conditions closest to the time the bug occurred and work outward. This makes it more likely to find the race condition as usually there is some locality to a bug. This does not have to be the case, in which case it would be neat to offer other heuristics, such as targeting specific threads or data for race conditions.

I often develop multi-threaded applications for Windows in both user and kernel mode. While a system like PRES could be useful sometimes, I have not needed it due to other tools working well enough. Between static analysis tools (PREfast and Static Driver Verifier) and dynamic analysis tools (Driver Verifier, Application Verifier, UMDH), I can typically be warned of race conditions without waiting for them to occur. When a bug occurs, a dump of the process (available on any Vista+ box) can usually pinpoint the problem. Kernel level code typically bug checks the system quickly after a problem, also producing a dump that can be used.

That said, PRES can still have its place for some heisenbugs that occur in the field.

Wednesday, November 4, 2009

More strategy patterns

The patterns in this post cover different ways to dividing up data in an algorithm for processing. I have not had the opportunity to work with these patterns personally yet.

Geometric Decomposition
This pattern covers dividing data up into chunks to be processed concurrently. The one thing that struck me as interesting was the necessity in many of the examples for optimizing for hardware. Deciding the size of chunks and number can both be affected by the underlying hardware for some algorithms.

Pipeline
In this pattern, data is stuffed down a pipeline where different stages can work on different objects at the same time. Think of an assembly line or a CPU pipeline. While it is used most frequently at a low level in hardware where one part of the pipeline focuses on a specific task, it can be used at a higher level as well. The assembly line is one example. This pattern would be useful any time it is faster to have individual threads focusing on one task in a system. I think this could be easier to implement, even if the speed difference is minimal, than having each thread perform everything.

Data Parallelism
This pattern was pretty much non-existent, with only a paragraph currently written.

Armstrong Chapter 6

This chapter dealt with the practical aspects of creating applications in Erlang. A program can consist of numerous processes, performing a worker or supervisor role. I found his approach straightforward and the modules easy to understand due to intentional programming.

I also found it interesting how a small set of behaviors abstracted out the majority of the types needed for the entire system. Client/server, event handling and finite-state machine modules covered the majority of functionality required in a parallel system. It is nice to be able to abstract this out, as it reduces the amount of complex code that needs to be tested, and helps with the fault tolerance of the system.

Between these behaviors and the supervisor abstraction, a nice API is available for the developers.

Monday, November 2, 2009

More Patterns

We read three more patters:

Task Parallelism
This pattern covers a strategy for implementing algorithms. Many algorithms can benefit in a parallel system by performing distinct tasks in parallel. For example, performing computations on every vertex in a graph presents the parallel opportunity of running a task on each vertex.

I have the most experience is running OS level processes and threads in parallel computing. This pattern requires finding the best granularity for a task and where to run a task, but I don't think you need to be a hardware expert to determine this. One only needs to know the relative costs of running tasks, such as over the network vs. locally.

Recursive Splitting
This strategy pattern covers algorithms that use recursion to find a solution. I thought this paper was the best of the three, as it had great examples and illustrations. The key to this pattern is producing more than one task per recursive task, as it allows for parallelism.

Discrete Event Pattern
The discrete event pattern is another strategy pattern covering using events in an asynchronous system. The order may matter, as events may cause other events through the system. This paper read and looked like a rough draft of a pattern, and as such was harder to follow.

Armstrong Chapter 5

This chapter covers building a fault tolerant system. First, supervisors are used to detect when a process crashes. The supervisor can by an AND type, where if one child crashes, all are restarted, or an OR type, where only the faulty child is retried. I can see the OR model being common, as sub tasks hopefully do not need to know about other sub tasks. AND is useful in the cases where the tasks are dependent on the success of the other tasks.

Armstrong then covers the differences between exceptions, errors and failures. Exceptions occur whenever the run-time does not know what the do. Programmers then decide if these are truly errors or not by catching them and handling if necessary. Actually, the decision is not to be made by the programmers, but by the designers according to Armstrong. The specification for a function should tell what to do in the error cases, otherwise the programmer should just error out. This gives functions well defined behavior, but at the cost of needing to have good specifications. Problems are then specification problems, and are easier to recognize and fix. I think this is quite beneficial as a result, at the cost of more time up front spent in design.

Wednesday, October 21, 2009

Armstrong Chapter 4

This chapter in the thesis on Erlang dealt with programming techniques. The two big topics covered were fault tolerance and abstracting out concurrency.

The author pointed out that concurrent programs are harder to write, so making a module that takes care of all the concurrent part separate can be a big gain for maintainability and reliability. Because Erlang only supports one way of communicating between processes (message passing), the language can be fairly simple to use when performing this task.

The fault tolerance discussion was quite interesting. The author listed several practices that help, including letting other processes handle the failure, crashing on an error and intentional programming. As part of intentional programming, Armstrong recommends NOT programming defensively, something sometimes taught religiously on the security side. However, the author is not saying to NOT check arguments, but that Erlang automatically treats unrecognized input as an error anyway. Having this feature built in to the programming language eliminates potentially confusing code meant to capture error cases.

Some Computational Patterns

In this post we'll look at three computational algorithms: Dense linear algebra, graph algorithms and monte carlo.

The Dense Linear algebra pattern was new to me. I have (unfortunately) not had the opportunity to take linear algebra, but I could still understand the pattern and see when you would need it. I thought the write up for this pattern did the best job of illustrating points with pictures than the others that have been looked at.

The Graph Algorithms pattern I thought tried to do too much. I have fairly good background in graph theory and algorithms, so none of the algorithms were new to me. The authors did do a good job of pointing out the parallel opportunities available in each algorithm, but didn't include this on all of them. There are so many graph based algorithms that only some of them could be highlighted, meaning the treatment of each one was rather short. More detail would be useful in several cases.

The Monte Carlo pattern is a statistical pattern that I have seen described once before. The writeup made sense and I could understand it.

Monday, October 19, 2009

Event Based and Map Reduce Patterns

Map-Reduce and Event Based patterns can be common when creating parallel programs.

Event based architectures typically subscribe for notifications with some server, which then sends the notifications when a signal occurs. This is common in GUIs; for example, registering for when a window size changes and then performing action in a callback when it does. One thing I thought was missing from this pattern was the context passed with the event. Some events may require data, others may only want to know the event occurred. At any rate, how this context is handled by the component sending the events deserves some treatment.

Another thing to consider in this pattern is error handling. This can take many forms - errors when registering, dispatching or the processing the callback. It depends on this situation if it is useful or not. For example, a GUI program sending a callback about a new mouse location probably doesn't care what happens in routines receiving this event. On the other hand, someone waiting on an object to perform an action probably wants to know if the object is unexpectedly deleted or crashes. Otherwise, resources may be tied up indefinitely.

Map-Reduce is the pattern of performing some computation on a bunch of object in parallel (mapping), then gathering the results (Reduce). I do not have much experience with this pattern, but it does have some great applications. The most famous one is probably Google's paper on the pattern extending it to run on a cluster. Anytime some action that is side-effect free needs to be applied to every item, this pattern is a candidate for implementation.

Armstrong Chapter 2

The Armstrong thesis paper details using the language Erlang when developing a concurrent application. It is notable for its use in switching equipment.

On of the key features in Erlang is its fault tolerance. This is achieved partially by running modules in separate software processes and then only communicating with read only messages. By not sharing data, a crash in one process cannot affect others. This approach would also work with OS processes, although the overhead can be high. Given the right requirements, it may be necessary. While threads are faster, they can typically access all other data in the same process and corrupt it.

Another big theme is building concurrency into the language primitives. While this does ease some of the development, I think a lot of its benefits can be gained through libraries that abstract out the same parts. Putting it in the language itself makes development easier, but possibly at the cost of flexibility. In this case, it is acceptable as the message passing and communication are only allowed in one form.

Wednesday, October 14, 2009

Patterns

I finished reading three different architectural patterns - pipe and filters, layered systems and iterative refinement algorithms. It was good to read the short definitions of the problems and see how to write a pattern.

The pipes and filters and layered systems pattern we have discussed before. When put into this format, the main thing added over the previous papers was a Forces section and a more concise solution section. This allows an architect to gain a quick idea of how the pattern can be applied to a problem. The previous papers contained a lot more implementation details, showing the typical problems you might face and how to overcome them, and lessons learned from existing implementations. While needed when actually doing the implementing, the architect may not need it up front.

The iterative refinement algorithm was a new topic defining a pattern in algorithms where some steps are repeated until a good enough solution is produced. Having taken algorithms and data mining, I can see when this pattern could be useful, but I have not run across it on my job.

CHESS

CHESS is a tool developed by Microsoft Research in order to discover automatically find bugs in highly concurrent systems. These "Heisenbugs" can otherwise be quite difficult to reproduce due to only occurring when a specific interleaving of threads happens.

To solve the problem, CHESS captures non-deterministic inputs, focusing especially on synchronization APIs that can cause different threads to run. By taking control of this and then allowing CHESS to deterministically decide which path to take, bugs can be found and reproduced. Each run through CHESS takes a different path.

As a Windows developer (including quite a bit of kernel mode), I was impressed with the work done in this paper. They wisely chose to intercept data at a layer higher than the kernel, where they would otherwise lose some of the context needed. I have spent days tracking down concurrency problems, and this tool would make it easier.

I also was intrigued by the search algorithm for determining which state to check next. Because any thread can be pre-empted, I knew when I started the paper that the potential different thread interleavings are practically infinite. They showed that most bugs could be reproduced with only a few threads since all options are searched, and that pre-empting is usually not too interesting. Keeping it too a minimum and only using fair schedules makes the search space manageable.

Monday, October 12, 2009

Refactoring for Reentrancy

This paper was the third one on automatically refactoring programs for parallelism. In this case, the tool enabled programmers to change programs to make them reentrant, by removing global references, using lazy initializers and warning about unsafe API calls.

The approach taken by the authors requires that the developer make some changes to optimize the program when finished. The given benchmarks for analyzing the results were far from impressive - some programs ran even slower despite using multiple threads due to the overhead created by the getters and setters. The program could also take substantial time to run.

I think the tool could still be useful in some situations where a program is being refactored with the goal of running several copies simultaneously. I would also have liked more reasoning on why some methods were rejected at the beginning of the paper, such as making an environment block. It requires a lot of code change, but this approach did to, it would be interesting to see them contrasted.

Rereading the Classics

This chapter dealt with the design of object oriented design by reviewing Smalltalk. This language truly treated everything as an object, although it did not become popular.

I found this chapter interesting in that it showed the strengths of the language, but then also compared it to physical architecture. Fallingwater and the Villa Savoye were used as parallelisms for Smalltalk, where something has a beautiful architecture, but is not practical for everyday use. The two aforementioned architectural building have been used as examples for new architects, but neither of them were suitable to live it, due to a leaking roof or other problem.

Likewise Smalltalk's features have found their way into more recent programming languages as the features were beautiful. But in this case, being beautiful is not enough. As the book ends, it correctly concludes that usefulness is of equal value in architecture.

Wednesday, October 7, 2009

Relooper

Relooper is another automated tool for helping programmers parallelize programs during refactoring. It helps turn Arrays into ParallelArrays and automatically finds when loops can be transformed using the new API, presenting all the changes to the developer.

The new APIs being given are quite useful to programmers. I think it helps reduce errors that may otherwise occur when performing parallel computations. In this case, when performing some operation on all items in an array, it can easily be incorrectly implemented leading to off by one errors. Plus, how the array is accessed may be done in a way that is NOT safe in a parallel setting and managing the resources of the threads doing the computation is more overhead for a programmer. The API hides this and lets the developer focus on the task at hand - creating efficient code.

The paper presented several areas for quantifying the usefulness of Relooper - correctness, speed, number of changes, and gained speedup. While these are helpful, it would also be nice to see the usability, based on feedback from others. This can be hard to obtain due to needing others to actually use the tool and provide feedback, but can be beneficial in deciding if a tool is truly useful. Can others use it too, or not?

Functional vs. OO Design

This chapter compared the modularity and flexibility of functional programming languages vs. object oriented programming languages. The author admitted up front that his knowledge of functional programming was limited compared to his knowledge of object oriented, and I think that showed in the comparisons. I think his treatment was fair on the areas he covered, but a functional expert may have thrown in some more areas for comparison. He did a great job of showing how object oriented design can cleanly address some issues found in functional programming and perform on par with the functional strengths.

Functional programming can be quite flexible in that operators and parameters are treated in the same manner, making it easy to extend. However, object oriented does a better job of modeling problems, and reduces the amount of programming through inheritance, something not available in functional programming.

Of course, I have much more experience as well with object oriented program languages then functional, which is limited to some Lisp. I think it is most useful for when formal verification or other analysis is need on the code, as it provides a clean way to automate the process due to disallowing side effects.

I had not played before with Agents in object oriented design, and found the solution fairly elegant as well.

Monday, October 5, 2009

Concurrencer

Concurrencer is tool to automatically refactor Java code, enabling it to take advantage of new concurrent APIs. Atomic integer operations, concurrent hash map, and a fork/join thread pattern are all supported by the tool.

This approach is useful if the code is already "close" to being parallel friendly. For example, it detects locking when accessing variables and uses the information to decide whether or not a transformation can be applied. If the locking is absent when needed, the program is going to need to be either fixed or redesigned before being able to take advantage of the new APIs.

The semi-automated approach was also useful, as the tool was by the author's admission neither completely correct or complete. Blindly applying changes could cause errors in programs. By allowing the programmer to be involved, tools like this can let the programmer indicate his intent, rather than automatically making changes based on actual implementation.

KDE Development

This chapter in Beautiful Architecture dealt with the structure of the KDE project with two case studies. Akonadi is the backbone of personal information management(PIM), used by email and similar applications. Threadweaver is the library used for highly concurrent operations.

Overall, I found the presentation quite biased toward open source development. Granted, this was trying to show the advantages of their architecture, and especially team development, but using straw man logical fallacies is not the way to do it.

Putting that aside, it was interesting to see the thought process used in arriving at decisions. It was hard for the team to arrive at a decision, because a consensus had to be arrived at when deciding how to implement the KDE PIM project. In a more formal team structure, a leader would make the decision and the team would have to live with the choice. In the KDE environment, greater buy-in is generated by having a consensus before beginning development, but at the expense of time in convincing others. Perhaps it would have been worthwhile to prototype different solutions and then obtain concrete metrics for going forward. On my last product we had a couple of options for ways to implement a design, so we prototyped the solutions to evaluate what would work best. Any thoughts?

Wednesday, September 30, 2009

A Java Fork/Join Framework

The Java Fork/Join framework is meant to simplify parallel programming in Java. It allows the pattern of forking an algorithm into several parallel tasks and then joining the results to be abstracted out by the developer.

I found it interesting that they left it up to the developer to still determine when to actually use separate threads. This makes it useful if you know that for some threshold the algorithm can be solved faster than with separate tasks, you can use the alternative method rather than a full task.

The authors implemented this in Java and showed that garbage collection is a major hit as the the number of threads grows, due to the pausing of all threads when the collector is running. I think this same kind of framework can be written on modern OSes in a faster language, but it will not be as portable as the given solution. For example, on Windows one could use Fibers or other smaller units than threads if needed.

Emacs: Creeping Featurism as a Strength

Emacs can be a rather polarizing subject, as most people either love or hate it. This chapter put forth the architecture of emacs as a good way to support add-ons. The following questions and answers address this architecture.

1. Is it possible for a system like Emacs to be created in a non-open 
source way?

Yes. The key strength of emacs is the ease of creating add-ons. It is quite possible to design such
a system in a commercial setting. The key is documenting how to create the add-ons and making
the extra features as easy as possible to create.

2. What are some of the disadvantages of a system like Emacs?
Finding what you want. When the base feature set is limited, everything is available as add-ons.
This can make finding certain features difficult as they may not be accessed in the most intuitive
way.


3. What architecture decisions have allowed Emacs to grow like it
has?
The ease of adding new features. When developers don't have to worry about display and other
subsystems that are ancillary to what they want to do, it makes it simple to work on.

4. When is avoiding complexity a good/bad argument for
implementation?
The only time I can think of when it would be bad is when something such as performance has a
higher priority than maintainability.

5. Do you think Firefox will replace Emacs?
No. =) The world will probably end first.

Monday, September 28, 2009

Our Pattern Language

Our Pattern Language is a paper defining patterns used during parallel programming. Different patterns are grouped into different categories: the interrelated architectural and computational patterns, parallel strategy, implementation strategy and concurrent execution patterns.

I thought their division was reasonable. While the paper lacks depth on describing each pattern, other papers can give the details of why and when to use each pattern. This paper tackles the problem of why they are needed at all and to facilitate communication between people working on parallel programs. When the language is defined, less confusion of terms occurs.

As parallelism becomes more prevalent with multiple cores in each CPU, programmers need to learn to take advantage of it. The problem is not so much in the tools available to develop with, but in educating programmers on how to design programs to take advantage of the parallelism. Knowing that these patterns exist for creating such programs is half the battle, and this paper helps on that front.

Jikes: A Metacircular VM

A metacircular VM is a sandbox written in the same language as the programs it is running. In this case, Jikes is a Java runtime written entirely in Java!

While this takes a bit of a performance bit, it has the advantaged of being able to take advantage of the facilities of the Java run-time such as managed code and garbage collection. However, it is not quite as fast. It is also not usually good practice from a security standpoint to implement an interpreter for a language is the same language, but in this case may be acceptable due to Java sandbox.

Jikes had to implement its own threading model due to the lack of support in operating systems when it was created (1997) for support of potentially hundreds of threads. By providing their own threading model they are able to support as many threads as needed. While the OS limit isn't as much of an issue today (see Pushing the Limits of Windows: Processes and Threads), having a consistent model can make portability a little easier.

Wednesday, September 23, 2009

Adaptive Object Model

The Adaptive Object Model is a programming model that provides the ability to just describe an object and allow the interpreter to model the object for you. This avoids the need to compile a new object every time something new is added to a system, instead requiring just a description that can be added dynamically.

I found this pattern quite interesting, as it provides a lot of flexibility, with the cost of more work for the initial design and implementation. Maintenance and adding new features should be must simpler when this model is used for a system, but this only makes sense if there are potentially many different objects that may be added over time.

To avoid objects needing to know about other objects, abstractions are used to represent attributes and business rules. This allows different objects to have different attributes and ways of validating these attributes without requiring the interpreter to know about all the different possibilities. I can see this pattern being quite useful for certain situations.

JPC: A Java based x86 Emulator

JPC is a Java based x86 emulator that is capable of launching a full OS.

What advantages do emulators have over VMs? What advantages do VMs have over emulators?
An emulator is fully run in software, it does not allow the actual code to run on hardware at all. A VM typically runs the code on the processor, at a much faster speed, while an emulator can run code for one hardware on a totally different platform.

Why would one prefer to use a Java emulator like JPC over a C++ emulator like Bochs, and vice-versa?
A Java implementation gives the security of the sandbox and ease of portability without recompiling, at the sacrifice of some speed.

Are there any performance and/or security considerations the JPC design team missed?
They didn't mention how few full OSes they can currently boot. Until it is capable of running common OSes, it will not be used for some of the security applications, such as auditing users without their knowledge.

For what purposes can you see yourself using an emulator like JPC? Any interesting uses on your mobile phone?

I would typically use an emulator for debugging otherwise hard - to - debug code, such as the bootup sequence of a computer. It provides the ability to save at any point, making is possible to debug tough race conditions if one can be produced once.

Monday, September 21, 2009

Gardian: A Fault-Tolerant OS Environment

Guardian was the OS used by Tandem starting in the 1970'2. Its goal was to eliminate all single sources of failures in an effort to create an extremely reliable system, and became popular for ATMs an other critical infrastructure.

Security was not a strong point of this architecture. The only thing guarding privileged code is the location and privilege bit in a register. If these can be manipulated, admin access can be achieved by untrusted components.

Due to the messaging bottleneck and other overhead, the system was not very fast or terribly scalable. This led to its downfall as regular hardware became more reliable without sacrificing speed.

Big Ball of Mud

The Big Ball of Mud architecture is what many projects end up as - a bunch of code tangled together with no clear boundaries. This may happen over time as fixed are placed in the easiest place in the effort to get something together quickly.

The authors listed a couple of ways to prevent this that I agreed with - code reviews and refactoring. The problem with many products is that time is not budgeted for this as it may seem superfluous. The main benefit - lower maintenance costs over the long term - is deemed beneficial enough to risk delaying putting the product on the market. This may in fact be the case in which case the manager made the correct choice! If the product works to the customer's expectations, is needed immediately, and will not need much maintenance, the reviews and refactoring may be overkill. Not every architecture needs to be beautiful.

I have worked on code that was supposed to be throwaway code that ended up being used. Now if code is going on the shelf as as part of IRAD, I check that it is easy to understand and handles errors. Rapid prototyping may be needed some times to reduce risk during development, but time should be allotted for actual cleanup if the prototype is going to be used in the final project. Putting in the extra effort up front makes no sense in the cases where the prototype ends up being scrapped anyway.

Wednesday, September 16, 2009

Layered Architecture

This pattern refers to the practice of layering services on top of each other, with the prime example being the OSI network layers.


My main exposure to this pattern has been in network stacks, having written some of the layers for one. This approach makes it less cumbersome to add layers, such as ICMP when IP is already separate. They also recommend in the paper decoupling the layers, through callbacks if necessary. I can say from personal experience that this works quite well until someone new doesn't follow the architecture. From there it is a downward slope toward becoming unmaintainable.

With the evolution of mobile technologies more people expect to be able to access software from more devices, where do you see this expectation having the biggest impact on the architectural layers (ranging from close to the client to close to the hardware or anywhere in between)?

I believe the impact is in two places, the hardware layer and the presentation to the user layer. The hardware is different, often with substantially less memory and resources, thus requiring changes. Also, the way a person interacts with mobile devices is substantially different from a PC, and this presentation layer needs to be changed accordingly.

Tuesday, September 15, 2009

Beautiful Architecture: Xen

Xen is an open source virtual machine capable of running an sevreal OSes beneath it. One of the early contributions of Xen was its use of paravirtualization. Xen needs to capture all interaction with the OS, and older x86 systems made this impossible as some instructions which should have been privileged were not, such as sidt. Other VMs solved this problem by using binary translation, a way of catching these instructions before they executed and replacing them. This is an expensive operation and Xen improved it by rewriting the binaries in the OS before they were installed. This one cost penalty was negligible compared to the savings incurred when running the VMs.

Thankfully, today processors provide a special mode for hyper visor VMs such as Xen to use. Due to the open source status of Xen, major vendors such as Intel and AMD contributed the code as it provided a good reference for others to use. This makes the VMs even faster.

I also appreciated the use of a separate domain for the controlling of the VMs running in Xen. This separation helps security by removing potential vectors of attack from the OSes being virtualized by Xen.

Monday, September 14, 2009

Pipes and Filters

This architectural pattern is quite common. I have worked on it personally when doing work in the windows kernel. Both the file system stack and network stack use this pattern, as any driver can plug in a filter in different spots without needing to know who is directly above or below. This is helpful as it gives a standard API for developers to work with and be interoperable with both the OS and third party filters in the system.

In this case, the filters are passive, waiting on input coming from a device or for data to be written to the device. This is beneficial in reducing the number of threads and time spent in the kernel. Because all filters are in the kernel, to context switching is needed either, reducing the time needed for marshaling data as would be required in other cases.

Sunday, September 13, 2009

Beautiful Architecture: Facebook Growing Up

This chapter covered the architecture of Facebook. Facebook, as a social networking site, has personal information available that can indicate the preferences of individuals on the web site. This information could be extremely useful to other sites that want to use that information, either for marketing or other applications.

The architecture of Facebook keeps security at a forefront, as no information can be divulged without an individual allowing it. Third party sites can interact with the information either remotely through the API or using FQL (a way of batching API requests). Alternatively, information can be displayed on the Facebook site itself using FBML, a limited version of HTML. In both of these cases, all interaction with data occurs on Facebook's servers, ensuring nothing is displayed that should be hidden.

I thought Facebook did a great job of keeping the architecture simple enough to understand, but still protect security of individuals by proctoring all interactions with the data. They also copied well known language paradigms in SQL and HTML to create FQL and FBML respectively. This makes the learning curve much easier for third party developers, ensuring that these interfaces are actually used and benefit Facebook by providing more content for users.

Wednesday, September 9, 2009

Excerpts from Christopher Alexander

We read a couple of chapters from books by Christopher Alexander, who advocated patterns for creating physical buildings in the 70's. For him, a pattern is like the word of a sentence, and patterns put together create a building instead of a sentence. The way they are structured follow more patterns in order to create a "grammar" for the language.

I think it would be interesting to see how many of the building patterns could be applied to software. For example, one of the patterns for building was to design the building in such a way that more intimate rooms are farther away from the entrance where visitors come. For example, the foyer, then formal entertaining space, then kitchen, then bedroom. In software, this could apply to the design of GUIs - make the administration part that is rarely used several clicks farther than the typically used interface.

Any thoughts?

Tuesday, September 8, 2009

Resource Oriented Architecture

This chapter in Beautiful Architecture dealt with the benefits of the architecture the World Wide Web uses. This would be useful inside many businesses, as many finding items on the web is often easier than finding things on the company network, an observation that I know holds true where I work anyway!

The REST architecture was held up as the best architecture in this scenario, which consists of the GET, PUT/POST and DELETE verbs. While only 4, I think they are fine for managing information, as creating, editing, viewing and removing information are the only things that need to be done, and these are covered.

It is also important in this architecture to separate the information from the address. Decoupling these two parts allows one to change the information without breaking any existing users/connections. This is important in providing reliability to users.

Saturday, September 5, 2009

ArchJava - Architecture Language

ArchJava is a descriptive architectural language that builds on top of Java. It ensures that anything written in its language does not violate the architecture, for example, communication modules is only possible where these points are defined.

This could be helpful as it builds on top of the type safety to prevent the programmer from violating the architecture, make it easy to diagram the architecture and easier to refactor.

However, as it stands now, it would need several improvements to be used commonly. The architect still has to write code in the language, or teach others how to. The graphing was not shown in the paper, and being able to visualize makes it much easier to understand architecture than looking at a definition in code.

Perhaps the biggest limitation is the inability to coordinate between multiple projects. This makes it impossible to use to describe the architecture for some projects, such as the Making Memories architecture described in the previous post. It could not describe the communication between the sides and the rendering farm, or between third party applications. Any comments?

Friday, September 4, 2009

Beautiful Architecture: Making Memories

Making Memories describes the architecture used for photography labs, where pictures are taken in a studio, enhanced and ordered at the studio. They are then sent to a processing center where they are rendered and printed, then sent back to the studio for pickup by the customer.

In designing the new software, the architects solved many problems, including concurrency issues at the studios, compiling the software, making the GUI easy to use and making the most use of the bottleneck - the rendering pipeline. They also recognized the need to make everything easy to upgrade since there are hundreds of distributed sites.

I especially appreciated their solution for keeping their DVD formats opaque. Because third parties need to interact with it, they correctly anticipated that the third parties may write their own tools to grab the format, making it impossible to change without breaking it. This is an example of Conway's law - software is structured around the communication structures. To solve the problem, they created a loader that parsed the DVD and called routines. This is a useful solution to remember when creating interfaces third parties may use.

Wednesday, September 2, 2009

4+1 Architectural View Model

Let's say you're a software architect and you want to know how to arrive at and document a an architecture. This paper puts forth a process for accomplishing this objective. Architecture is documented from separate views, each with its own goal.

I thought this was a great approach to follow, for two reasons. One, in my experience, use cases or scenarios can be extremely useful for verifying what the customer is envisioning, and this process uses them extensively (the "+1"). Second, it is flexible. I often work on small projects, and following an exhaustive process for documentation will take longer than actually doing the designing and implementing.

I have not used the 4+1 model before, but I can envision using it more in the future. Anyone else have experience with it?

Monday, August 31, 2009

Beautiful Architecture: Chapter 3

Chapter 3 of Beautiful Architecture presents the designing of project Darkstar, a framework for MMO games and virtual worlds.

I enjoyed seeing how the decisions were made in identifying problems and the best solution for the framework. I can relate to their issues of developing frameworks for other people to use transparently. They still had to educate developers on how to create objects that do not defeat the parallelism available. I developed a framework at work for other people to use, along with a complete user guide on best practices for keeping modules self contained, etc. Still, other developers would break rules and cause issues, showing the need for better education or validation =) It's fun to see other people start to use stuff you've created

Field Guide to Boxology

The authors of this paper put forth the idea of architectural styles, and trying to define common patterns used for solutions, not problems. They classify mainly the styles used for handling data and communication in architectures, then suggest patterns to follow based on need.

I enjoyed their breakdown and thought it was interesting, but is it enough? The job of the architect is far from over after picking the needed data communication. How execution is structured, style, modularity and many other concerns will still have to be addressed. Should these be categorized too? Does one type of data architecture naturally lead to one type of process for development? This paper is a good start, and opens the door for more research in the field.

Sunday, August 30, 2009

Beautiful Architecture: Chapter 2

Chapter 2 of this book was a case study: A Tale of Two Systems. The first was poorly designed and a disaster to work on, the second well thought out and enjoyable for the developers.

I found it interesting how much the process helped the second, good system, with eXtreme Programming being used. How much do you think the process used affects the system for good/bad? I think it has a rather large impact, due to the numerous facets a process addresses, such as style, design documentation, etc., which can make it easier for others to follow what is happening. I've worked on a couple of CMMI projects, which can output a large amount of documents, some rather unnecessary. However, it was required by the customer and thus necessary to the success of the project, plus we were able to remove parts that made no sense for small projects. A dose of commen sense can go a long ways =)

Saturday, August 29, 2009

Beautiful Architecture: Chapter 1

This book shows how to design software architecture through examples. The first chapter is expected background, defining terms and what architecture is. I liked the comparisons between physical architecture, musical architecture and software design.

I saw one comment on another blog related to this claiming that all developers should be architects. Would you agree that this is the case? Based on experience, I don't believe this is necessarily true. While anyone designing software is to some degree an architect, not all programmers need to be architects. Once an architect has set a style and assigned a module to some programmer, that programmer does not need to have design skills. At my company, new college graduates fall into this category typically. Sure the work needs reviewed to ensure the assignment is fulfilled, but the programmer does not have to worry about the big picture or creating standards, that is done by the architect.

Any comments?

Tuesday, August 25, 2009

First Post

Sadly, I must now begin a real blog =( Since this is for a class on design patterns, I've named it so that it may be used after the class, yet still make the several posts following half-way relative to the topic.

After this course is over, I may yet turn a different type of pattern - a pattern for life in general. Enjoy!