The Last Mile
The Last Mile - The problem with FOSS
This article is about FOSS (free and open-source software). The expression "The Last Mile" refers to supply chain or delivery services that get the products or packages into people's hands. A larger company or service may produce it and ship it across the world, but it is usually up to a local company/carrier to bring it the last mile. I see FOSS as having a "Last Mile" problem. The problem is that it's missing proper incentives to maintain/finish/optimize projects which become important to a large set of computer users. Occasionally I benefit from this problem - I optimize other people's software for a living; some of that software starts out as an open source project.
Problem #1 (lack of upstreamed improvements)
A few years ago I optimized a FOSS tool (ETCPACK - Ericsson Texture Compressor) for a large Silicon Valley company. This tool is used for compressing RGB images into a lossy texture that GPUs can directly decompress. My optimizations gave a significant speedup and I asked my supervisor to upstream the changes so that others could benefit. The response was typical, but not surprising - "The legal department won't approve of this, so forget about it". I've been in similar situations with the same decision when working with other companies. In this case, I felt quite strongly that this was a shortsighted move because there was no competitive advantage to be lost by sharing the code, it simply makes artists and programmer's jobs go faster.
Problem #2 Intrinsic vs. Extrinsic Motivation
A great majority of open source projects start out in a similar humble way - the author had a need or desire to write some software and shared it with the community. The reasons for sharing it can be altruistic or not. This is intrinsic motivation - when you want to get something done because "reasons". For me, I sometimes want to test an idea for making code execute faster, or I need something for a personal project (e.g. a LCD display library). Maybe the existing solutions don't quite fit or I want to do it "My Way ™️". All of these reasons are perfectly valid and some great FOSS projects started this way. What comes next? Well, the project will get supported (or exist) as long as the original author wants it to. Perhaps other people join in, fork the project, and make improvements. Great, this happened with libjpeg. The JPEG (joint photographers expert group) released some reference code in the early 1990s to get people started and unfortunately no one improved it (at least publicly) for a long time. Someone was eventually inspired to create the libjpeg-turbo project. It may have been for personal (intrinsic) reasons or maybe a company seeded the money to do the work. This is a major flaw in the whole system - most people on the Earth operate in a capitalist society and need money as a (extrinsic) motivation to work. The avenues for getting paid to work on open source are mostly non-existent.
Problem #3 The FOSS Checkbox Item
Another aspect of FOSS I've encountered too many times is when companies "Support FOSS and the community" because it serves their business needs (e.g. they sell hardware and share FOSS projects to support their hardware). When pressed to actually support the FOSS community (e.g. financial support for other's code they profit from), crickets. The other frequent situation is the FOSS purist who won't share the code used in the "binary blob" in their products. They support FOSS as long is they get to keep trade secrets when they feel like it serves their needs. A good name for some of this behavior might be "FINO = FOSS in name only". Microsoft is a recognizable name in the FINO category.
Problem #4 Theft
The various licenses in use for FOSS (e.g. LGPL, Apache) are there to protect the rights of the author(s). The truth is that a lot of FOSS ends up in commercial products with the attribution/copyright notice removed, no royalties paid and no respect for the original author's rights. There's not much that can be done about that. I'm confident that this has kept a lot of great code from being shared.
Problem #5 The Wasted Cycles
There are billions of computers in use these days - they form "the internet" as well as the private machines running in homes and offices. A lot of that code has been carefully optimized to use as few cycles / gigawatts as possible. You can bet that the most optimized software in use will be the code which runs the cloud services of big companies like Google, Amazon and Apple. Their services and processes need to be efficient because the electricity and time represent a measurable and significant part of their operating expenses (How much does one search cost?). That's a strong incentive for the big companies to use the most efficient processors and optimize their software to the fullest... but what about the users who pay to rent those machines (aka virtual machines / cloud services)? Do you think Amazon cares how inefficient your python scripts running on their machines are? This is the issue that irks me the most. Amazon/Google/Apple actually benefit financially from your processes being wasteful. They may provide tools and advice for helping you to optimize your code, but they still benefit from your inefficient use of their computer time - the slower your code, the more money they make. This isn't a surprise for a capitalistic arrangement, but it is detrimental to the environment because most electric generation is still not emission free.
The Last Mile
All of these problems with FOSS bring us back to the point of this article - for someone like me to contribute to the FOSS community purely out of intrinsic motivation is really shortsighted. The lack of extrinsic motivation limits the possibilities of making significant improvements to popular projects which could in turn have significant cost savings at scale. Let's use an example that shows my point. The libjpeg project comes with several command line utilities. One of these is jpegtran - a tool to transform JPEG images (rotate/crop/convert/etc). Several of these options are specialized code which uses specific knowledge of JPEG encoding to perform functions like lossless cropping. If you were to decompress a JPEG image, crop it, then recompress it using the normal JPEG functions, it would suffer additional distortions and loss of quality. The jpegtran CLI is used in many server back-end processes to cleanly extract pieces of larger images without further degrading the quality. jpegtran does the lossless cropping by decoding the image only to the point of the DCT coefficients; it essentially keeps the pixels in the frequency domain instead of doing the lossy part (converting them back and forth from the spatial domain). This idea also happens to save time since the forward and reverse discrete cosine transforms are skipped. The libjpeg-turbo project optimized this even further. Now we're at the point where things will become clear. The way that jpegtran does lossless crop is reasonable, logical and assumed to be the best/right way to do the job. I thought about this problem and a new idea entered my head. I spent many hours prototyping my idea and it worked. My version of lossless crop is much faster than jpegtran-turbo. When I say much faster, I don't mean a 25% improvement, I'm talking about 300-500% faster. On my MacBook Air M1 I created a command line utility which takes the same parameters as jpegtran. I ran it multiple times against jpegtran to eliminate and file/memory caching differences. Here are the results when requesting a 1024x1024 crop from a 7200x5400 image:
time ./jpegtran -crop 1024x1024 ~/Downloads/large.jpg > out.jpg
0.20s user 0.03s system 86% cpu 0.268 total
time jpegcrop -crop 1024x1024 ~/Downloads/large.jpg > out.jpg
0.06s user 0.01s system 96% cpu 0.069 total
Great breakdown
ReplyDelete