Monday, April 17, 2017

Alan Kay on Computer Science

Alan Kay is a computer scientist and pioneer who was part of the Xerox PARC team of about 30 researchers that developed many of the key concepts of today's hardware and software technologies.
This post contains some famous keynotes and other talks by Alan Kay including quotes and comments.

See also: Alan Kay on Object-Oriented Programming

Normal Considered Harmful

  • 05:00 We must know about the past (the pioneers of computing) to invent the future.
  • 13:53 We cannot invent the future by using vendor computer hardware and software.
  • 34:29 Knowledge almost always trumps IQ. A change in perspective is worth a lot of IQ points.
  • 36:31 Clever hacks don't scale well and worse keep broken things around for too long.
  • 39:45 Learning a new idea requires almost as much creativity as the original invention.
  • 49:27 Wayne Gretzsky theory of hockey: Why are you a so much better hockey player than everybody else? Everybody else just goes where the puck is, I go where it is going to be.
  • 1:01:08 All understanding begins with our not accepting the world as it appears (Susan Sontag).
  • 1:02:17 Brains were designed for survival and coping, not for great inventions. Science is a way to get around that limitation.

Programming and Scaling

  • 06:50 The biggest problem we have as human beings is that we confuse our beliefs with reality.
  • 08:21 Make-and-fix paradigm: Nowadays, computing is mostly tinkering and not engineering.
  • 18:03 The internet is one of the few human artifacts that behaves like a living organism.
  • 25:11 Smalltalk (OO) mistake: Objects are too small! The scale jump from molecules to a living organism is incredible compared the scale jump when trying to make objects. Idea: Make much more capable universal objects and try to build things out of that.
  • 33:11 Most people can only experience the present in terms of the past. (Marshall McLuhan)
  • 30:05 Our strain of humanity is on the planet for about 192.000 years (tracing mother's mitochondrial DNA) and we only invented science 400 years ago. That's why IQ does not count that much.
  • 37:00 Past, Present, Future: The past is enormous!
  • 42:43 Computing is mostly tinkering at this time, there's not much engineering, math, or science.

Is it really "Complex"? Or did we just make it "Complicated"?

  • 1:13:10 Next generation publish/subscribe systems in UI/UX design: Widgets communicating by a publish/subscribe methodology to announcements of events.
  • 1:38:00 Computer science is the science of processes. It is about thinking, reasoning, and talking of processes as well as representing, constructing and debugging them both in hardware and software.

@ SAP

  • 12:47 Our perception of the future is mostly just a little increment on the present.
  • 13:01 Innovation is just taking an idea or invention that already exists into the marketplace.
  • 19:19 Problem finding is much harder than problem solving in order to make progress.
  • 21:14 You are doing research only so long as you can change your mind. Making decisions consolidates one's mind.
  • 21:53 Most software in the world is absolutely not designed!
  • 25:01 Thinking is not remembering!
  • 37:50 Big data: What we need is not big data but big meaning (including descriptions for processes, relationships and constraints).
  • 40:33 Building with gears does not scale (< 1000 gears)! Biology scales!
  • 42:58 The internet is one of the few human artifacts that behaves like a living organism.
  • 44:19 Learning how to code is like the last thing you wonna learn about computing. Computing is about systems, not about algorithms, not about if-statements; it is about powerful ideas that are made into descriptions computers can interpret.
  • 56:55 How do you learn how to bike? Using a low bike without pedals. Bicycle training wheels are actually anti-learning! Lessons learned: Software called "user-friendly" very often isn't.

Power of Simplicity

  • 10:01 You get simplicity by finding a slightly more sophisticated building block to build your theories out of. The inability to fix the existing building blocks is one of the largest problems that computing has today. The building blocks (abstractions) help in putting stuff into the right context.
  • 14:33 WYSIATI: What you see is all there is.
  • 23:53 You need to solve the context, not just a problem!
  • 24:14 Finding out about the real problem is the big deal and it may be much harder than solving the problem itself.
  • 32:39 What is your company's 10 year plan? Umm...
  • 49:27 Wayne Gretzsky: A good hockey player is going to where the puck is, and a great hockey player is going to where the puck is going to be.
  • 50:11 "Better" and "Perfect" are the two enemies of "What Is Actually Needed".

The Future Doesn't Have to Be Incremental

  • 21:55 Human universals by anthropologist Donald Brown (e.g. coping, social, language, culture, fantasies, stories, news, art, etc.). Most popular software products work as technological amplifiers for at least on such human universal.
  • 28:15 Linux is a budget of bad ideas.
  • 29:12 Real inventions: E.g. writing and reading, abstract math, model-based science, democracy, equal rights, slow deep thinking, etc.
  • 30:48 Isaac Newton changed the way of how people think.
  • 35:23 Wayne Gretzsky: You miss 100% of the shots you don't take.

The computer revolution hasn't happened yet

  • 16:45 OOP architecture: As complexity starts becoming more and more important architecture is always going to dominate material.
  • 24:11 It only takes about 50 cell divisions (iterations) to make a baby.
  • 35:11 In contrast to biology computers are slow, small and stupid.
  • 37:01 Cell membrane acts like a pattern matcher and it keeps most of the things out as much as it keeps certain things in.

The Best Way to Predict the Future is to Invent It

  • 11:39 We all have a duty to the next generation, whether or not we have children!
  • 13:26 Our brain is mostly set up for reacting (System 1) and it tries to avoid real thinking (System 2).
  • 27:31 "We must ensure that human wisdom exceeds human power" (Vi Hart)

Sunday, April 16, 2017

Operating System 101

From Andrew S. Tanenbaum's "Tanenbaum-Torvalds Debate - Part II".
No flame wars, just operating system and distributed system architecture.

My view is that you want to avoid shared data structures as much as possible. Systems should be composed of smallish modules that completely hide their internal data structures from everyone else. They should have well-defined ‘thin’ interfaces that other modules can call to get work done. That’s what object-oriented programming is all about – hiding information – not sharing it. I think that hiding information (a la Dave Parnas) is a good idea. It means you can change the data structures, algorithms, and design of any module at will without affecting system correctness, as long as you keep the interface unchanged. Every course on software engineering teaches this. In effect, Linus is saying the past 20 years of work on object-oriented programming is misguided. I don’t buy that.

Once you have decided to have each module keep its grubby little paws off other modules' data structures, the next logical step is to put each one in a different address space to have the MMU hardware enforce this rule. When applied to an operating system, you get a microkernel and a collection of user-mode processes communicating using messages and well-defined interfaces and protocols. Makes for a much cleaner and more maintainable design. Naturally, Linus reasons from his experience with a monolithic kernel and has arguably been less involved in microkernels or distributed systems. My own experience is based on designing, implementing, and releasing multiple such operating systems myself. This gives us different perspectives about what is hard and what is not.

See also: Microkernels are slow and Elvis didn’t do no drugs

Friday, April 7, 2017

On Building Reliable Automotive Software Systems

During the last years me and my team built various automotive software systems in the connected car domain as well as in the body domain.
Before that, we built Android-based infotainment systems, mobile internet routers and some kind of wireless display like Miracast.
Over time, our work became highly inspired by two software platforms and their characteristics: Erlang and Android.
Erlang's influence came mostly from its reliability characteristics and its shared-nothing methodology. Android provides a modular, component-based application framework including a software development kit and documentation which we wanted to have for all kinds of automotive software systems as well.
This led to the developement of the Mindroid application frameworks.

What is Mindroid?

In short, Mindroid is a component-based application framework similar to Google's Android, including a software development kit and documentation. It builds upon the Actor model as core system architecture building block and provides an event-based programming paradigm.
Currently, there are three variants of Mindroid.
  • Mindroid.java targets the Java platform
  • Mindroid.cpp targets native platforms, like Linux or QNX Neutrino RTOS
  • Mindroid.ecpp targets deeply embedded systems without dynamic memory management, like AUTOSAR OS, CMSIS RTOS or even bare metal
One of Mindroid's main goals is to provide a slim platform to develop highly reliable (distributed) software systems. Other goals and their prerequisites are:
  • Modularity: Components with clear interfaces, threading and dependencies
  • Reuse: Set of reusable components across projects and platforms
  • SDK: Sustainable, public APIs crafted by an API first design approach (Finding good abstractions and truly care about naming things)
  • Reliability, testability and refactorings: No shared state between components
  • Software quality highly benefits from Actor model design approach
    • No complex critical sections
    • Callbacks run in right thread contexts
    • Low energy, CPU time and memory requirements
  • Logging (No long-lasting debugging sessions)
  • Slim platform: Simplicity is prerequisite for reliability
  • Scalability: Distributed systems running multiple Mindroid instances on different nodes
Mindroid relies on the Erlang-style actor process model to achieve that goals. The core Actor model is mainly based on the Android Thread, Looper, Message, MessageQueue, Handler and Binder classes. Together with the Process class Mindroid implements deployable components and component isolation comparable to Erlang-style process isolation. The component isolation assures that there is no shared state across component boundaries. This is done by exchanging only POD types a.k.a. plain old data structures and component interfaces (actor endpoints) on component interface level. Using such component interfaces one can access further components. Furthermore, each component clearly defines its own threading behavior within the hosting process to achieve true component isolation regarding data (no shared state) and the runtime environment (process and actor).

Slide 5 below illustrates the Erlang-style actor process model using a CarFinder component that relies on a LocationManager for location updates.


For future, we plan to implement Erlang-style distribution transparency for services and service discovery. And we would love to have a Rust variant of Mindroid.

See also:

Saturday, March 11, 2017

Characteristics of an efficient engineering team

An efficient engineering team offers a fun and challenging place to work at. From my personal experience the following mindset forms the basis of such a team.

We truly care about things
  • Caring means acting
  • Caring means pushing things forward
  • Caring means questioning ideas, concepts and decisions
  • Caring means listening to customer feedback
  • Caring means answering questions and providing feedback in time
  • Caring means continually monitoring project progress
  • We are pragmatic while caring about things
Failures happen, but we are able to quickly analyze, find and fix them
  • Logging helps us in analyzing and finding bugs quickly (without long-lasting debugging sessions)
  • Simple and elegant design help us in fixing problems instantly as well as in maintaining and refactoring our code base without fear
  • Tooling is very important to achieve fast bug fixing turnaround times
We communicate openly
  • Open communication means keeping others informed
  • Open communication works like a push system, not like a pull system
  • Open communication must no result in overstimulation by steady interruptions
To understand is to invent
  • We keep asking why and question until we understand all the stuff
  • Understanding all the code and technologies is a prerequisite to quality
Best Practices
  • Strive for simplicity
  • Keep an eye out for beauty and aesthetics in your code base no matter if it is about architecture, naming or something else
  • Reduce risk by integrating early and often
  • Read code, review code! By reading code one learns so much, both from the good and the bad parts of the code base
  • Fail fast, but don't give up too easily

Friday, February 24, 2017

Psychology and Behavioral Science (not just) for Computer Scientists

This post contains some few excerpts from the book Drive: The Surprising Truth About What Motivates Us from Daniel H. Pink.
The field of psychology and behavioral science currently preoccupies me a lot mostly due to personal struggles in seeking purpose.

Societal Operating Systems

Societies have operating systems: the laws, social customs and economic arrangements sit atop a layer of instructions, protocols and suppositions about how the world works.
A big part of our societal operating system consists of a set of assumptions about human behavior.

Societal OS v1.0 code name "Try to survive" was the operating system in place at the beginning of human mankind
Societal OS v2.0 code name "Humans are more than the sum of their biological urges" is the operating system that currently has the biggest installed base
  • Supports more complex societies
  • Cooperation
  • Rewards and punishments to build and scale complex economies
  • Profit maximization
  • Enabler for the industrial revolution
  • Algorithmic, rule-based work
Societal OS v3.0 code name "Intrinsic motivation" currently has a small but growing installed base out there
  • Purpose maximization
  • Social benefit principle
  • Supports really complex societies
  • Powerful, new business models: Open-source
  • Humans have a drive to learn, to create and to make to world a better place
  • Effectiveness
  • Heuristic tasks

Intrinsic motivation

Intrinsic motivation depends on autonomy, mastery and purpose.
To develop intrinsic motivation an undertaking itself must provide freedom, challenge and purpose to the people.

Self-Determination Theory
The self-determination theory describes three innate human needs: competence, autonomy and relatedness. Satisfying these needs results in motivation, productivity and happiness.

The Open-Source Movement
  • Enjoyment-based intrinsic motivation is the strongest and most pervasive driver
  • The fun of mastering a given software problem and the desire to give a gift to the community
  • Social benefit principle replaces maximum profit principle
  • Open-source people are mostly intrinsically motivated purpose maximizers
  • Open-source people love creativity, interest and self-direction
Flow
Flow in positive psychology is the mental state of operation in which a person performing an activity is fully immersed in a feeling of energized focus, full involvement, and enjoyment in the process of the activity. People can frequently reach "flow" in case of optimal challenges.
  • Flow, the deep sense of engagement, is the oxygen of the soul we need to survive
  • People are much more likely to reach a flow state at work than in leisure
  • Why at work? Maybe due to clear goals, immediate feedback, challenges matching to our abilities
  • This way, organizations can enrich people's lives
Autonomy and Self-Direction
  • Autonomy over 4 aspects of work: what people do, when they do it, how they do it and whom they do it with
  • People should focus on the undertaking itself rather than on the time to do it
  • People should contribute rather than just show up and grind out the day
  • The opposite of autonomy is control. Control leads to compliance, autonomy leads to engagement
  • The billable hour is a relic of societal OS 2.0
Mastery
  • Mastery is the desire to get better and better at something that matters
  • Only engagement produces mastery
  • The modern workplace's most notable feature may be its lack of engagement and its disregard for mastery
  • Flow is essential to mastery
  • Grit may be as essential as talent to high accomplishment
  • Mastery is an asymptote. You can approach it without ever reaching it
  • Mastery can be an ethic for living
  • Mastery is a mindset! -> Intelligence is something you can develop
  • Mastery is a pain! -> Mastery requires effort over a long time
  • Does your company or team have and share a mastery mindset?
Carol Dweck: What people believe shapes what people achieve.
  • Our believes about ourselves and the nature of our abilities (our self-fears) determine how we interpret our experiences and can set the boundaries on what we accomplish
  • Effort is one of the things that gives meaning to life. Effort means you care about something, that something is important to you and you are willing to work for it
  • It would be an impoverished existence if you were not willing to value things and commit yourself to working toward them
Purpose
  • It is in our nature to seek purpose
  • The secret to high performance isn't our biological drive or our reward and punishment drive but our third drive: our deep-seated desire to direct our own lives, to extend and expand our abilities, and to live a life of purpose
  • Societal OS 3.0 is built for purpose maximization
  • Purpose maximization is about seeking the right goals
  • A healthy society or healthy organization needs sustainable purpose
  • "They" and "we" companies are very different places
  • What is your company's purpose?
  • What gets you up at morning? What keeps you up at night?

Extrinsic motivation

  • Good for algorithmic, rule-based tasks
  • If-then rewards require people to forfeit some of their autonomy and therefore undermining the intrinsic motivation toward the activity
  • Try to offer now-that rewards instead of if-then rewards by praising and providing positive feedback with useful information
  • Rewards narrow people's focus
  • Goals may narrow people's focus, decrease cooperation and decrease intrinsic motivation

See also:

Saturday, August 6, 2016

Danny Hillis: The Pattern on the Stone

"The greatest achievement of our technology may well be the creation of tools that allow us to go beyond engineering - that allow us to create more than we can understand."

Tuesday, January 26, 2016

Unsere Art zu leben - Eine ehrliche Gesellschaftskritik

Es gibt Menschen, die die freien Gesellschaften mit Gewalt bekämpfen. Und es gibt Menschen, denen diese freien Gesellschaften Gewalt antun - ohne dass dies hier groß auffallen würde.
Immer, wenn irgendwo auf der Welt Terroristen gemordet haben, müssen Regierungschefs vor Kameras treten und einige Sätze dazu erklären. Eine traurige Routine ist das geworden; Angela Merkel bewältigt sie mit Variationen ein und derselben Bemerkung. Die Terroristen zielten auf "unser freies Leben in freien Gesellschaften", sagte sie nach dem Anschlag von Istanbul. Sie griffen "unsere Art zu leben" an, sagte sie nach dem Horror von Paris, vor zwei Monaten. Es sind Worte des Trotzes und des Beharrens - was in dem Moment auch angemessen ist. Doch in ihnen verbirgt sich viel mehr, als das Floskelhaftige in ihnen zum Ausdruck zu bringen scheint.
Dass Gesellschaften sich von Terroristen nicht intellektuell herausfordern (oder gar einschränken) lassen, ist eine Binsenweisheit, die nur Terroristen nie kapieren. Wer andere in die Luft sprengt oder erschießt, mit dem diskutiert man nicht, den bekämpft man. Dennoch steckt in einer Formulierung wie "unsere Art zu leben" nicht allein eine Kampfansage an Mörder. Denn zum einen mag sie die Freiheit beschreiben, nach Istanbul zu reisen und dort die Hagia Sophia zu besichtigen; oder den Besuch von Kneipen, Restaurants und Konzerten in Paris, München, Kopenhagen. Sie mag zum Ausdruck bringen, dass in freien Gesellschaften jeder nach seiner Façon leben darf; Männer, Frauen, Schwule, Heteros, Fleischesser, Vegetarier, Gläubige, Atheisten.
Das ist das eine, das von dem Begriff umfasst wird. Das andere ist das, worauf ausgerechnet Angela Merkel einmal hingewiesen hat, und zwar ganz und gar nicht im Zusammenhang mit Terror. Es ist einige Jahre her, es war die Neujahrsansprache kurz nach dem gescheiterten Weltklimagipfel von 2009. Da dachte sie laut darüber nach, "wie wir unseren Wohlstand erhalten" - nämlich "indem wir unsere Art zu leben und zu wirtschaften ändern".
Es wäre geboten, die Lebensart in den reichen, freien Gesellschaften als beides wahrzunehmen: als Errungenschaft und als gigantisches Problem. Gelebt wird hier ein Freiheitsverständnis, das absolut ist. Nichts ist den Menschen hier fremder als Beschränkung im persönlichen Alltag. Freiheit ist erstens der Kneipenbesuch und zweitens, dass der Wirt Heizpilze auf den Gehsteig stellt, damit man auch im Januar den Wein und den Barsch draußen genießen kann. Freiheit ist, dass Amerikaner 6,6 Milliarden Kilowattstunden Strom allein für Weihnachtsbeleuchtung aufwenden, mehr als Tansania im gesamten Jahr verbraucht. Freiheit ist, ein Auto zu bauen (und zu kaufen), das pro Kilometer 224 Gramm Kohlendioxid ausstößt. Benedikt XVI. war ein Papst, der nicht mit Beispielen erklärte, sondern der lieber grundsätzlich formulierte. So gelang ihm der Satz, "dass Materie nicht nur Material für unser Machen ist" - den Menschen des 21. Jahrhunderts muss man an eine solche Banalität erinnern. Denn der macht und macht; und wer denkt schon über Terrorismus, Klimawandel und Flüchtlinge nach, wenn er unterm Heizpilz sitzt.
Das ist in Wahrheit die größte Herausforderung: die Auseinandersetzung mit einem so alltäglich gewordenen Lebensstil. Das Nachdenken darüber, ob zum Beispiel aus Westafrika auch deshalb so viele Flüchtlinge kommen, weil europäische Kutter den Einheimischen dort die Barsche weggefischt haben? Wie viele ökonomische und kulturelle Konflikte künftig allein deshalb drohen, weil Menschen ihre Heimat für unbewohnbar erklären und nach Europa aufbrechen; mal der Armut wegen, mal um einem Krieg zu entkommen, immer aus Perspektivlosigkeit? "Wir haben unseren Wohlstand auf dem Rücken der Entwicklungsländer aufgebaut. Das wird nicht mehr lange gut gehen. Diese Spannungen entladen sich." Hört sich nach Brot-für-die-Welt-Sätzen an. Ihr Urheber kommt aber aus der CSU, es ist der Entwicklungsminister Gerd Müller. Er fügt noch hinzu, dass man sich nur nichts von Obergrenzen für Flüchtlinge versprechen soll: "Die Menschen werden uns nicht fragen, ob sie kommen können."
Die Klima-Apokalypse wird zwar nicht dadurch verhindert, dass Politiker im Dezember in Paris eine Vereinbarung dazu getroffen haben. Doch ohne eine solche Vereinbarung würde sie ganz gewiss eines Tages zur Realität. So wie der Vereinbarung erst noch Taten folgen müssen, so werden Menschen zu ebenjenen Taten nur bereit sein, wenn es eine Instanz gibt, die sie orchestriert. Niemand gibt auch nur Teile seiner Lebensweise auf, also von Freiheit, solange er mit Recht sagen kann: "Nützt ja doch nichts." Solange bleibt die Menschheit ein Gewusel aus Räuberbanden - und in dem trachtet jeder nach Beute, solange es noch Beute gibt. In diesem Gewusel wird es immer einen Unterschied geben zwischen abstrakten Einsichten und konkretem Handeln. Ausgerechnet ein katholischer Bischof lebt diesen Unterschied auf unübertreffliche Art vor. Erst schrieb er neulich einen Aufsatz, in dem er "die Industrienationen" aufforderte, die Emissionen zu reduzieren. Dann schaffte er als Dienstwagen einen VW Phaeton an, das Auto, das 224 Gramm Kohlendioxid pro Kilometer ausstößt. Typisch Bischof? Typisch Mensch.
Die Frage des 21. Jahrhunderts ist, ob der Mensch lernen wird, dass Wohlstand nur durch Verzicht zu sichern ist - siehe Merkels Neujahrsansprache von 2009 -, und ob er bereit ist, sich diesen Verzicht organisieren zu lassen. Jeder Gemeinschaft geht es schlecht, wenn der Einzelne alle Freiheiten haben darf; sei es eine Nation oder eine Weltgemeinschaft. Jeder Staat beschneidet - zum Beispiel durch Steuern - die Freiheit seiner Bürger. Wenn die Einzelnen weniger haben, haben alle zusammen mehr. Das ist der Gedanke dabei. Lässt sich dieses Prinzip auf die Welt als Ganzes übertragen?
Es gibt Menschen, die "unsere Art zu leben" mit Gewalt bekämpfen, und es gibt Menschen, denen diese Lebensart ihrerseits Gewalt antut. Auf einen "sozialen Klimawandel" stimmt der Essener Bischof Franz-Josef Overbeck die Deutschen deshalb ein (der mit dem Phaeton, übrigens). Er meint damit, dass Zuwanderung kein vorübergehendes Phänomen sein wird. Nur welches Ausmaß sie bekommen wird, das können die Menschen in den reichen Ländern mitbestimmen - noch.

Wednesday, October 7, 2015

Building a car (from the perspective of a pragmatic software engineer)

The ideas for building a car from the perspective of a pragmatic software engineer came up during the series development of an Internet of Things (IoT) platform and control unit for a German automaker.
The automotive industry is currently undergoing a disruptive technology change mainly driven by software. The self-driving (electric) car will not only change the automotive industry but also society and urban life.
To enable this technology change, the automotive industry finally needs sustainable software platforms that allow for building reliable and scalable software systems in a very short time. (And I am definitely not talking about AUTOSAR here.)
Hence, the automotive industry needs to build software platforms including software development kits (SDK), great APIs, documentation and tools. The automakers must design for simplicity, modularity and security. This requires them to look at the car as a (classical) distributed system of computers and to find good abstractions to easily manage each system and the whole system of systems.
Today, I often see a lot of bad abstractions or no abstractions at all in automotive software systems. That results in slow development cycles, way to much (unreadable) code which is hard to maintain, and at worst, unhappy developers.
Having some good fundamental abstractions would allow for building applications from a set of reusable components that form the basic building blocks of this new software platforms. (And no, I don't have AUTOSAR Software Components in mind.)

So what kinds of software platforms do you need to build a car?
  • Deeply embedded (body) domain (engine, powertrain, light, etc.)
  • Infotainment domain (Head units, dashboards and head-up displays)
  • Internet of Things domain (secure cloud connectivity, eCall, WiFi hotspot, car sharing, over-the-air updates)
  • Driver assistance systems for self-driving cars (highly reliable, real-time number crunchers)
  • Private cloud (machine learning platforms to teach your self-driving cars, data mining to analyse customer behavior, online services like roadside assistance, etc.)
Deeply embedded (body) domain
Automotive real-time software systems of this domain run on embedded controllers with little CPU power and few memory. Therefore, application frameworks and libraries for these kinds of systems avoid or lack dynamic memory allocation and many other well-known abstractions. We have built our own application framework for this kind of deeply embedded systems, called Mindroid.ecpp.

Infotainment domain
Systems in this category are often the same as today's high-end smartphones. So why not use today's smartphone platforms for these kinds of system, or at least parts of it.

Internet of Things domain
Systems in this category are often the same size as today's mid-range smartphones. So why not use today's IoT application frameworks and smartphone platforms for these kinds of systems.

Driver assistance systems (for self-driving cars)
Hardware and software systems in this category are really big computing beasts. Due to its reliability and safety (ASIL) requirements, these are the most challenging and interesting automotive software platforms of the future.

Private clouds
Well, private clouds. Let's do it with Erlang technologies! (Or with any other well-known open source infrastructure.)
To be honest, building a machine learning and data mining platform really is some work to do. Today, only IT giants like Google, Facebook, Amazon, Apple, Microsoft, etc. own and operate such platforms. Hopefully, this will change.

Now let's bring the various car domains (yes, also the private cloud) together. As we learned from Alan Kay, the key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Hence, the connected car needs a simple, clean and robust messaging paradigm.
Choosing form the classical messaging paradigms of distributed systems, I think topic-based publish-subscribe messaging fits best for most use-cases. It allows us to build loosely coupled, flexible, scalable and easy to test (asynchronous) software systems. And it avoids dependencies, something that is really important when evolving systems. Furthermore, a publish-subscribe messaging infrastructure should support quality of service levels for at-most-once, at-least-once and exactly-once delivery to simplify the overall software architecture.
One can also add synchronous messaging systems, like Remote procedure calls. I always try to keep synchronous remote procedure calls to a minimum in order to avoid some of the dependencies (and shared state) they often introduce into distributed systems.
What data to exchange with the publish-subscribe messaging between the domains? Well, let's define a domain model for representing real-world (domain-specific) objects, processes and rules.
E.g. speed, mileage, door states, window states, sequences to safely open the car by a smartphone app, and so on.
Applications must only know about the application framework, the publish-subscribe mechanism and the domain model. They should definitely not know about which protocol to use for domain model exchange, serialization, model binding and many other things. This has to happen within the application framework and a publish-subscribe messaging service.
To evolve the domain model over time, protocols like Google's protocol buffers that allow for changing message formats without breaking backwards-compatibility provide great flexibility.
Using a publish-subscribe messaging mechanism abstracts away all the quirks of automotive bus systems and protocols like CAN, LIN, FlexRay, MOST or even Ethernet.
And of course you never have the "one size fits all" abstraction. E.g. besides publish-subscribe messaging you still need H.264 video streaming over RTP to connect your cameras to a driver assistance system, and others.

To sum up, the automotive industry should build application frameworks with a few simple building blocks for each domain and provide a variety of system services on top of it, e.g. logging, publish-subscribe messaging, power management (using wake locks and leases), etc. - just like Google did with the Open Handset Alliance.

Advice for ambitious system architects and application framework engineers
  • The most dangerous enemy of a better solution is an existing codebase that is just good enough - Eric S. Raymond.
  • Seriously think about threading and message-passing. Get the damn threading right by the application framework for the application developers. You are developing an application framework for developers, not against them!
  • Modularity is there for reusability of components and to ease refactorings within software systems while trying to minimize dependencies between the components. Try to minimize the number of control units within a car!
  • Keep an eye out for beauty and aesthetics in software systems. This has to do with software architecture and naming. Naming is so important!
Links

This is my personal opinion about software engineering in the automotive sector, not that of the company I am working for, nor of anybody else in that company.

Friday, May 2, 2014

RISC design principles for project management

When David A. Patterson and Carlo H. Sequin designed the first RISC processors in the beginning of the 80s they soon realized that designing instructions that could be issued (started) quickly was the key to good performance. While the initial emphasis was on simple instructions that could be executed quickly, they learned, that how long an instruction actually took mattered less than how many could be started per second.
I learned that the same principles apply to good project management in the last few years. Thanks RISC designers!

Tuesday, October 1, 2013

Mindroid - Android everywhere

Mindroid is an application framework that lets you create applications using a set of reusable components - just like Android. The name Mindroid has two different meanings. On one hand Mindroid is a minimal set of core Android classes and on the other hand these classes also form Android's mind (at least in my opinion). There are three versions of Mindroid focusing on different domains.

The feature-richest version is Mindroid.java. It is a complete application framework intended for machine-to-machine (M2M) communication projects and the Internet of Things. It is almost completely Android API-compliant with minor exceptions since Mindroid even runs on Java v1.4 (Java SE and Jave ME CDC) platforms like IBM's J9 Java virtual machine on Qualcomm's modem chipsets running an L4 microkernel OS. Mindroid.java also includes an application framework documentation. For the future, I plan to make Mindroid run on Java ME 8.

Another version of Mindroid is Mindroid.cpp. It is written in C++ using reference counting and other nice gimmicks. Currently, Mindroid.cpp is not really a complete application framework but focuses on Android's messaging and concurrency features. Nevertheless, it provides all messaging abstractions for implementing a lot of applications - the Android Transporter Player is one such example. At the moment Mindroid.cpp runs on POSIX operating systems like Linux, Android or QNX Neutrino RTOS and it uses dynamic memory allocations.

The third version is Mindroid.ecpp. This deeply embedded version of Mindroid is similar to Mindroid.cpp but it runs on tiny embedded operating systems like CMSIS-RTOS for ARM Cortex-M processors and it also runs on AUTOSAR-OS for various embedded processors. Such deeply embedded environments often lack dynamic memory allocation which is also not required by Mindroid.ecpp.

Why?

One of the main reasons for building Mindroid is the fantastic Actor implementation of Google's Android operating system. This actor model is the core building block of Android's whole software architecture. In all versions of Mindroid (and Android) an Actor is implemented by the Looper and Handler classes. A Looper has a thread and a message queue. The threads blocks on the message queue waiting for something to do. To put something into a message queue there is the Handler class. Each Handler also has a handleMessage method for processing messages. An example of this scenario is given in the documentation of the Looper class. Each Handler is attached to exactly one message queue (and thus to one Looper) at creation time. A message object always refers to its Handler that will process it later. Now think of software components in terms of Handlers. Software components (Handlers) talk to each other by passing messages. For example, you can run each Handler on its own Looper (thread) if you like. But you are also allowed to put multiple Handlers on the same Looper. (Android is also able to put multiple Handlers in different operating system processes that communicate with each other using the Binder IPC.) This behavior (software architecture) is changeable at will without a need to change the inner workings of a software component.

How?

Here are "Hello World" examples (using two Handlers) for all versions of Mindroid. One Handler prints "Hello " and the other one "World!" once in a second resulting in "Hello World!" outputs.

Mindroid.java
public class HelloWorld extends Service {
  private static final String LOG_TAG = "HelloWorld";
  private static final int SAY_HELLO = 0;
  private static final int SAY_WORLD = 1;
 
  private Handler mHelloHandler = new Handler() {
    public void handleMessage(Message message) {
      switch (message.what) {
      case SAY_HELLO:
        System.out.print("Hello ");
        mWorldHandler.obtainMessage(SAY_WORLD)
          .sendToTarget();
        break;
      }
    }
  };
 
  private Handler mWorldHandler = new Handler() {
    public void handleMessage(Message message) {
      switch (message.what) {
      case SAY_WORLD:
        System.out.println("World!");
        Message hello = mHelloHandler
          .obtainMessage(SAY_HELLO);
        mHelloHandler.sendMessageDelayed(hello, 1000);
        break;
      }
    }
  };

  public void onCreate() {
    mHelloHandler.obtainMessage(SAY_HELLO)
      .sendToTarget();
  }

  public void onDestroy() {
    mHelloHandler.removeMessages(SAY_HELLO);
    mWorldHandler.removeMessages(SAY_WORLD);
  }

  public IBinder onBind(Intent intent) {
    return null;
  }
}
Mindroid.cpp
static const int SAY_HELLO = 0;
static const int SAY_WORLD = 1;

class HelloHandler : public Handler {
public:
  HelloHandler(const sp<Handler>& worldHandler) :
      mWorldHandler(worldHandler) {
  }

  virtual void handleMessage(const sp<Message>& msg) {
    switch (msg->what) {
    case SAY_HELLO:
      printf("Hello ");
      sp<Message> message = mWorldHandler
        ->obtainMessage(SAY_WORLD);
      message->metaData()->putObject("Handler", this);
      message->sendToTarget();
      break;
    }
  }

private:
  sp<Handler> mWorldHandler;
};

class WorldHandler : public Handler {
public:
  WorldHandler() {
  }

  virtual void handleMessage(const sp<Message>& msg) {
    switch (msg->what) {
    case SAY_WORLD:
      printf("World!\n");
      sp<Handler> helloHandler = msg->metaData()
        ->getObject<Handler>("Handler");
      sp<Message> message = helloHandler
        ->obtainMessage(SAY_HELLO);
      helloHandler->sendMessageDelayed(message, 1000);
      break;
    }
  }
};

int main() {
  Looper::prepare();
  sp<Handler> worldHandler = new WorldHandler();
  sp<Handler> helloHandler = 
    new HelloHandler(worldHandler);
  helloHandler->obtainMessage(SAY_HELLO)
    ->sendToTarget();
  Looper::loop();

  return 0;
}
Mindroid.ecpp
static const int SAY_HELLO = 0;
static const int SAY_WORLD = 1;

class HelloHandler : public Handler {
public:
  HelloHandler(Handler& worldHandler) :
      mWorldHandler(worldHandler) {
  }

  virtual void handleMessage(const Message& msg) {
    switch (msg.what) {
    case SAY_HELLO:
      printf("Hello ");
      mWorldHandler.obtainMessage(mMessage,
          SAY_WORLD);
      mMessage.obj = this;
      mMessage.sendToTarget();
      break;
    }
  }

private:
  Handler& mWorldHandler;
  Message mMessage;
};

class WorldHandler : public Handler {
public:
  WorldHandler() {
  }

  virtual void handleMessage(const Message& msg) {
    switch (msg.what) {
    case SAY_WORLD:
      printf("World!\n");
      Handler* helloHandler = (Handler*) msg.obj;
      helloHandler->obtainMessage(mMessage,
          SAY_HELLO);
      helloHandler->sendMessageDelayed(mMessage,
          1000);
      break;
    }
  }

private:
  Message mMessage;
};

static uint8_t sHelloHandler[sizeof(HelloHandler)];
static uint8_t sWorldHandler[sizeof(WorldHandler)];

int main() {
  Message message;

  Looper::prepare();
  Handler* worldHandler =
    new (sHelloHandler) WorldHandler();
  Handler* helloHandler =
    new (sWorldHandler) HelloHandler(*worldHandler);
  helloHandler->obtainMessage(message, SAY_HELLO);
  message.sendToTarget();
  Looper::loop();

  return 0;
}

For more information on Mindroid please consult the Mindroid.java documentation and the examples provided with the application frameworks on GitHub.

Thursday, April 18, 2013

Concurrency: A single human body cell versus the internet

This week I asked Alan Kay (the inventor of OOP, Smalltalk, the Dynabook, and much more) if there are more concurrent activities going on inside a single human body cell than on the whole internet? Since he is a computer scientist as well as a molecular biologist he seemed to be the right person to answer this question. Here is a summary of the short conversation:

Hi Daniel

Good question -- and we have to work on the question some more in order to get a reasonable comparison.

Since matter is concurrently active at the subatomic level, the more mass we have the more concurrent activities -- so the Internet wins here because it has much more mass.

Things get a lot more tricky at the "cell mechanics" level. Typical human body cells have about 80 billion large molecules of about 10,000 types (the other 70% is water and other small molecules), and these are concurrently active. 
There are several billion computers on the Internet (plus many nuts and bolts computers such as routers) and we can guess that most of these have a few hundred processes each (and each with some number of threads) -- all of which are pseudo-concurrent (it's really how many CPU type things are operating).

So at the hardware level with real CPU like things, there are likely ~ 10 in each computer, and now more with multiples cores, so that gives us an estimate of around 20 billion real concurrent processes not counting routers and other infrastructure.

If we count pseudo-processes (which are logically concurrent), then I think in the Internet we've exceeded a single cell at the active large molecule as a process level of concurrency.

We have about 10 Trillion cells in our body that have our DNA (and about 90 Trillion that are microorganisms of many different kinds).

I think we are safe to say that the concurrent activities in one human body completely dominate the Internet.

However, I have not looked below the CPU level to processes at the hardware level .... perhaps you'd like to take a shot at estimating that!

Cheers,
Alan


Hi Alan,

thanks for your detailed answer. I really appreciate that you took the time to think about this. I came up with this question when thinking about concurrency (maybe also parallelism and message passing) as measurement unit for complex systems. There is no measurement unit for concurrency, I think. But its quite hard to define one, just like comparing the incomparable :-).
...
I also tried to google the answer to this question but since I am a software engineer and only a hobbyist in biology, I wasn't quite sure if I can count all proteins as concurrently active entities or if I should only count ribosomes, motor proteins etc. as concurrently active. On the internet I found that there are about 15.000 ribosomes in one single cell. If only counting ribosomes (which I think is not correct) would reduce the concurrency within a human body cell enormously. Hard to compare...

Thank you very much and best regards,
Daniel


Hi Daniel

You have to at least count proteins that are acting as enzymes -- they are continuously active. Also, you will be interested (and amazed) if you look at the dynamics of biochemistry (i.e. why does it work? How do the molecules "find" each other). These processes are happening concurrently.

I think it is hard to compare -- but mainly for "level" not for estimating how many entities are actually "in process" concurrently.

Cheers,
Alan


Really impressive, isn't it? And we software engineers think that today's multi-core computers provide concurrency and parallelism. |-O

Sunday, November 4, 2012

Concurrent Hello World in Go, Erlang and C++

This week I started taking a deeper look at the Go programming language since I am somewhat addicted to scalability, reliability, concurrency and message passing :-). The first thing I always do when playing around with a new software platform is to write a concurrent "Hello World" program. The program works as follows: One active entity (e.g. thread, Erlang process, Goroutine) has to print "Hello " and another one "World!\n" with the two active entities synchronizing with each other so that the output always is "Hello World!\n". Here is the concurrent Hello World program in Go, Erlang and in C++ using the Mindroid framework.

Go
package main

import "fmt"

func main() {
    sayHello := make(chan string)
    sayWorld := make(chan string)
    quitter := make(chan string)

    go func() {
        for i := 0; i < 1000; i++ {
            fmt.Print("Hello ")
            sayWorld <- "Do it"
            <-sayHello
        }
        sayWorld <- "Quit"
    }()

    go func() {
        for {
            var reply string
            reply = <- sayWorld
            if (reply == "Quit") {
                break
            }
            fmt.Print("World!\n")
            sayHello <- "Do it"
        }
        quitter <- "Done"
    }()
 
    <-quitter
}

Erlang
-module(hello_world).

-export([start/0, say_hello/2, say_world/0]).

say_hello(0, WorldPid) ->
    WorldPid ! quit;

say_hello(N, WorldPid) ->
    io:format("Hello ", []),
    WorldPid ! {sayWorld, self()},
    receive
        sayHello ->
            say_hello(N - 1, WorldPid)
    end.

say_world() ->
    receive
        quit ->
            quit;
        {sayWorld, HelloPid} ->
            io:format("World!~n", []),
            HelloPid ! sayHello,
            say_world()
    end.

start() ->
    WorldPid = spawn(hello_world, say_world, []),
    spawn(hello_world, say_hello, [1000, WorldPid]).

C++ (Mindroid)
#include <stdio.h>
#include "mindroid/os/Message.h"
#include "mindroid/os/Handler.h"
#include "mindroid/os/LooperThread.h"

using namespace mindroid;

static const int SAY_HELLO = 0;
static const int SAY_WORLD = 1;
static const int QUIT = 2;

class HelloHandler : public Handler
{
public:
  HelloHandler(const sp<Handler>& worldHandler) : 
    mWorldHandler(worldHandler), mCounter(0) {}

  virtual void handleMessage(const sp<Message>& msg) {
    switch (msg->what) {
      case SAY_HELLO:
        mCounter++;
        if (mCounter <= 1000) {
          printf("Hello ");
          sp<Message> sayWorld =
            mWorldHandler->obtainMessage(SAY_WORLD);
          sayWorld->metaData()->putObject("SayHello",
            obtainMessage(SAY_HELLO));
          sayWorld->sendToTarget();
        } else {
          mWorldHandler->obtainMessage(QUIT)
            ->sendToTarget();
          Looper::myLooper()->quit();
        }
        break;
    }
  }

private:
  sp<Handler> mWorldHandler;
  int mCounter;
};

class WorldHandler : public Handler
{
public:
  virtual void handleMessage(const sp<Message>& msg) {
    switch (msg->what) {
      case SAY_WORLD:
        printf("World!\n");
        msg->metaData()
          ->getObject<Message>("SayHello")
          ->sendToTarget();
        break;
      case QUIT:
        Looper::myLooper()->quit();
        break;
    }
  }
};

int main() {
  sp< LooperThread<WorldHandler> > wlt =
    new LooperThread<WorldHandler>();
  wlt->start();

  Looper::prepare();
  sp<Handler> hh =
      new HelloHandler(wlt->getHandler());
  hh->obtainMessage(SAY_HELLO)->sendToTarget();
  Looper::loop();

  return 0;
}

I think I really like Go (although Erlang is a bit more crafty :-)). Go eases developing scalable and reliable distributed systems while being a good to read language. Since you can also handle much more concurrent activities with one machine using Goroutines (compared to plain operating system threads) it also helps in saving energy.

Links