6.033 Paper #5:

X Window and the End-to-End Argument

Becky Wagenberg
March 14, 1995 Choosing proper placement of functions in a system is one of the main tasks of a computer system designer. The end-to-end argument is a proposition that addresses this important task. It argues towards moving functions upward through the layers of a system, closer to the programs that use them. (p.277) Applications of the end-to-end argument are especially evident in data communications networks. In such networks, one tends to view the communication subsystem as a separate module, thus enabling one to place functions either within it, outside of it, or somewhere in between. (p. 278) Specifically, one such example is the X Window system. Although the chosen design of X Window is unusual, it agrees with the main principles of the end-to-end argument.

The X Window system attempts to reduce overhead caused by translating between different byte-order schemes. The need for translation arises from the "holy war" between the big-endians, who assign the most significant bit of data first, and the little-endians, who assign the least significant bit of data first. X Window achieves reduced overhead by providing two different network ports; the big-endian clients send their requests and data to one port, while the little-endian clients send their requests and data to the other. Of course, the server itself is implemented on either a big-endian or a little-endian machine. This two-port structure reduces the number of byte-swaps for all possible combinations of client and server machines (since swapping must be done at most once). Yet, this structure is uncommon. Most network servers simply require that all data be presented at a single port in only one form. This may sometimes require up to two byte swaps (e.g. if both the client and server are big-endian but the port takes little-endian data).

Still, the two-port structure of X Window conforms with the end-to-end argument more than the normal one-port design. The main point of the end-to-end argument is that functions should be moved into applications, since at lower levels they may not be cost effective. In this regard, both the X Window two-port structure and the normal one-port structure coincide. In the two-port case, the client application must choose the correct port, while the server must swap bytes as needed (e.g. a big-endian server needs to swap bytes coming in through the little-endian port). In the one-port case, both the client and server applications must take care of byte-swapping. Therefore, in both cases there is some functionality implemented at the high level. Yet, there is another part of the end-to-end argument: "Sometimes an incomplete version of the function provided by the [low-level] communication system may be useful as a performance enhancement." (p. 278) It is precisely in this sense that the two designs differ. In dealing with byte-order, the one-port structure does not involve the communication subsystem at all. Instead, the client and server applications swap bytes themselves. On the other hand, the X Window ports, which are the direct cause of the reduced byte-swapping, are themselves part of the low-level communication subsystem. Therefore, X Window is an instance where a low level feature aids performance by reducing the amount of work required of the higher level. As such, the X Window system also conforms to this subtler performance aspect of the end-to-end argument.

All in all, it is evident that the placement of functions within a computer system is not a trivial task. The change made by X Window in adding a second port is just an example of the importance of careful division of labor between cooperating modules. The end-to-end argument is only an approach to dealing with this task. "[It] is not an absolute rule, but rather a guideline that helps in application and design analysis." (p. 285)