Archive for the ‘computer’ Category

Politics simulator

Friday, August 6th, 2010

I’ve occasionally thought it would be fun to have a computer game where you start out with some land, some people and some natural resources, and your job is to found a country and run it. You get to write your constitution, set up laws and so on and see how things unfold. You might also play the part of a politician once the country is set up. You might get voted out, which changes the set of powers you have (and makes the main next objective “get back into power”). Maybe there are other countries on the “virtual planet” – you can invade them, embargo them, make treaties with them etc. They have their own objectives. You get problems thrown at you (war, dissent, natural disaster and so on) and have to make changes to your policies to try to keep everybody happy.

Given the similarities between writing laws and writing code, I suspect this might devolve into a “programming game” style activity (albeit with a rather more political type of geekiness). I also suspect that there are so many aspects of human activity that would need to be simulated that making it realistic would be an overwhelmingly large task. But of course it doesn’t need to be perfectly realistic to be fun – it may be fun enough with just easy-to-implement large-scale economic features.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

Transverse wave

Thursday, August 5th, 2010

Right after creating the original Simple Harmonic Motion program, I wondered what would happen if you connected lots of masses and springs together in a line. I came up with what I’ve now translated into this:

Controls are the same – dragging the mouse moves one end of the “string”, the leftmost slider (or the + and – keys) controls the tension and the rightmost one (or the < and > keys) controls the friction.

Source code.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

Simple Harmonic Motion

Wednesday, August 4th, 2010

Some 14 years ago when learning about second order differential equations, simulating physical systems on computers and simple harmonic motion, I wrote this DOS program which (because it’s kind of fun to play with) I have now translated into flash:

The idea is very simple – it’s just a mass (the white ball) with a green pen, connected to a point by a piece of elastic (the white line). The point doesn’t move except when the mouse button is held down, when it moves to the mouse pointer location. This means that the mouse is essentially the forcing function for a 2D, second-order linear differential equation. Which means that (depending on the parameters) the mass follows the mouse pointer, possibly smoothing out its motion, possibly oscillating around it.

There are two slider controls on the right – the leftmost one (or the + and – keys) controls the tension and the rightmost one (or the < and > keys) controls the friction. Press escape to clear the screen.

Source code.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

Virtual physical tone matrix

Wednesday, July 28th, 2010

Here’s a virtual version of my physical tone matrix, implemented in Flash, so you can play along at home:

Much of the code is a direct translation from the C code in the non-virtual version, so it works in a way very close to the real thing. Even the sample rate and frame rate are close (though they are not synchronized – it’s not a cycle-exact simulation).

Click or drag on the screen to turn the lights on and off.

The knobs are (from top left) sustain, tempo, tuning and volume. Above and between the sustain and tempo knobs is the escape switch, which brings up or closes a menu of funcions. These are, from top left:

  • Sine wave (default)
  • Square wave
  • Triangle wave
  • Sawtooth wave
  • Random wave
  • Pattern editor (default)
  • Coarse waveform editor
  • Fine waveform editor (not particularly useful or easy to use)
  • Tuning editor
  • Miscellaneous editor
  • Save current pattern/waveform/tuning/settings to EEPROM
  • Load current pattern/waveform/tuning/settings from EEPROM
  • Toggle life mode
  • Toggle random mode
  • Toggle microtone keyboard mode

The miscellaneous editor shows 6 rectangles. Clockwise from top-right these are:

  • Patterns per loop (a 5-bit binary number) – if this is not 1, then whenever the pattern reaches the right a new pattern is loaded from EEPROM.
  • Fixed tuning – just disables the tuning knob. This exists in order to allow the tuning to be set more accurately on the non-virtual version, not really necessary on the virtual version
  • Update noise continually – when set, the waveform is continually updated with random data, so all frequencies sound the same. This is slightly different to the “random wave” waveform preset, where the 256 waveform components are initialized with random numbers but then don’t change, so there are some audible differences between playing them at different frequencies.
  • Beats per pattern – repeat before the pattern gets all the way to the right, useful for rhythms that don’t factor into 16.
  • Sustain override – overrides the function of the sustain knob so that this parameter can be set digitally.
  • Tempo override (a 16-bit binary number) – must be greater than 0×200 to work – smaller numbers are faster).

The EEPROM save/load functions load or save the data for the current editing mode (pattern, coarse waveform, fine waveform, tuning or miscellaneous). To use them, press save or load. The screen then shows the current EEPROM contents. Click on a location to choose where to save to or load from. Depending on the editing mode, 2-8 lights will be lit per “saved file”.

Fun things to try:

  • Put the PTM in random mode and light 10-16 lights. Then just sit back and listen to some randomly generated music for a while.
  • Draw a glider or Lightweight spaceship, put the PTM in life mode and turn the tempo all the way up to maximum.
  • Make a horizontal line in pattern editor mode, turn the sustain all the way up so that the sound is continuous, then switch to the coarse waveform editor (which was inspired by this). Click and drag around to move the “sliders” and see what sounds you can make.
  • Make sure the pattern editor is empty and then switch to microtone keyboard mode. The lit lights correspond to the white notes on a piano keyboard – the unlit lights are the frequencies in-between (i.e. it’s a 34-TET instrument). Try to play or tune or make some weird music. Trying the different preset waveforms is fun in this mode.
  • (Advanced) Try to create a different tuning such as major scale or chromatic (instead of the default pentatonic) using the tuning editor. Each line of the tuning editor represents a frequency as a 16-bit binary number (LSB on the left), in units of roughly 0.24Hz (16Mhz / 226).
  • (Advanced) Make some patterns and save them in consecutive locations in EEPROM, starting at the top left. Then use the “patterns per loop” setting in the miscellaneous editor to play them back in sequence and make a tune longer than 16 notes.

The copy and paste functions on the right-click menu work and are compatible with the original Tone Matrix applet.

Source code is here.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

USB device classes and usage pages

Thursday, July 22nd, 2010

The Universal Serial Bus interface specification includes various fields to specify what kind of device is plugged into a computer, and what numbers correspond to what buttons, lights and so on on the device. All these are documented in the Human Interface Device Usage Tables. When I discovered this, it provided me with some amusement as alongside the normal mice, keyboards, scanners there are some more exotic devices. Section 5, which describes “Simulation Controls” (i.e. standardized controllers for operating various simulators). As well as the ones you’d expect like a steering wheel (Usage ID C8) and a flight yoke (Usage ID 24) there are such controls as “Standard spaceship controls” (Usage ID 04).

I had no idea that spaceship controls were standardized. I suppose it makes sense, so that once you learn how to fly one sort of spaceship you could (in principle, in some sort of emergency situation) have some chance of operaing an unfamiliar craft. Of course, if that emergency situation is being kidnapped by aliens you’re probably out of luck as I doubt any alien spaceship designers have read the USB specification documents.

What’s even funnier is the “Standard magic carpet controls” (Usage ID 0B). Being a magical (not to mention fictional) mode of transportation, it seems quite amazing that magic carpets have standardized control mechanisms. You’d think the interface would be something as indistinguishable-from-sufficiently-advanced-technology as “just think about where you want it to go”, but the USB documents go into quite some detail about how to fly a magic carpet:

Allows a device to be generally classified as one that uses the standard control of a magic carpet. This control is a bar, grasped by both hands, that controls the Yaw, Pitch and Roll of the carpet.

The bar, at which the pilot sits, may be pushed forward or pulled back to cause the carpet to dive or rise, respectively. In the zero position, the carpet is in level flight. Pushing forward on the bar causes the carpet to nose down and generates negative values. Pulling back on the bar causes the carpet to nose up and generates positive values.

Turning the bar turns the carpet. In the zero position, the carpet travels straight ahead. Pulling back on the right side turns the carpet to the right and generates positive values. Pulling back on the left side turns the carpet to the left and generates negative values.

Rotating the bar rolls the carpet. In the zero position, the carpet travels level. Rotating the bar in a clockwise direction rolls the carpet to the right and generates positive values. Rotating the bar in the counterclockwise direction rolls the carpet to the left and generates negative values.

So there you go – now if you find yourself in a Persian golden-age fairy tale, you know how to get around.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

I am a monad

Saturday, July 17th, 2010

In the programming language Haskell, it is normal to work with functions that depend only on their input values, and which do nothing except return an output value. Functional programming is generally much easier to reason about, because there’s no chance of one piece of a program making a change to global state that affects an apparently unrelated part of the program.

This does leave the problem of how a function program can communicate with the outside world. Various approaches have been tried, and the one Haskell chooses is particularly elegant. Functions that need to accept input or produce output take an IO object as a parameter and produce a (generally different) IO object as the result. The IO object “encapsulates” the entire world outside the program. To actually run a Haskell program, the machine performs a sequence of IO transformations – taking one IO object, evaluating the program as much as necessary to determine the next IO object, and then actually performing the corresponding input or output operation before restarting the loop.

So there’s a sort of inversion between how we normally think about function evaluation and how the evaluation actually happens. One can’t really pass around the entire state of the universe as a parameter the way a C programmer would pass an int, so one must fake it by moving the “state of the universe” to the outside of the program and rearranging everything else so that it works the same way as it would if you could.

I can’t prove it, but I think there’s a very deep idea here with implications for how we understand the universe and our place in it. Much like pure functions can’t describe IO, it seems like physics as we understand it can’t describe human consciousness (in particular, subjective experience). Some suggest that this means consciousness is an illusion, but this has never been a satisfying answer to me.

Physics is done by describing the universe objectively – there are these particles at these positions and such and such a field had value x over here at this time (somewhat like values in a Haskell program). There are rules describing how the state of the universe evolves through time (somewhat like pure functions). But none of these things really seem to be able to describe what it is like to “feel” seeing the colour red (for example). Physics can describe a stream of 700nm wavelength photons hitting a retina, causing neurons to fire in particular patterns, some of which resemble the patterns that have occurred when the same retina received 700nm photons previously. These patterns then provoke other patterns which previously occurred in conjuction with the “700nm” patterns, and cause the release of small amounts of hormones. Understanding this system completely (which admittedly we don’t) would allow one to (in principle) predict exactly which previous experiences would be recalled by any given stimulus, and might even allow one to predict exactly how the stimulated individual would react. But none of this seems to be able to tell us what experiencing red is actually like because we have no way to describe subjective experiences objectively.

We experience the universe entirely from a subjective point of view – through our senses. The objective model is useful because it allows us to reason, communicate and simulate but I suspect that in saying that objective reality is the real think and subjective reality is just an illusion, we would be making a mistake and not seeing the forest for the trees.

Instead, I would like to suggest that we perform the same inversion that the Haskell compiler does. Instead of thinking of human beings as unexplained (possibly unexplainable) things within an objective universe, think of them as the IO hooks of the universe: input from free will (assuming that it exists) and output to subjective experience. This IO doesn’t (necessarily) go to “another universe” – it’s just a primitive, axiomatic thing that may have no more relevance to our objective universe than the implementation details of the IO monad do to a pure functional Haskell program. Experiencing life is running the program.

One important difference between the universe and a Haskell program is that a Haskell program only has one IO monad, but the universe seems to have many subjective observers in it. Having multiple IO monads would be a problem for a Haskell program because the IO monad defines how the program is actually evaluated – there’s only one “real universe” for it to run in. But there’s no problem having multiple non-IO monads – if the monads can’t communicate with each other through the outside world (only through the program) you can have as many of them as you like. Since people can’t communicate with each other except through the physical universe, there’s no problem here.

Does this mean that one observer in the universe is priviliged to be the “IO monad” whilst everyone else is a p-zombie? From the point of view of that observer, it certainly seems like that is a possible way of thinking about it, but since there’s no objective difference between an IO monad and a non-IO monad (as long as the monads only communicate objectively), I’m not sure the distinction is meaningful.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

Bailout thoughts

Thursday, July 15th, 2010

In 2008, the US government spent a large amount of money bailing out financial organizations troubled as a result of the subprime mortgage crisis. The fiscal conservative in me thinks that maybe socializing losses isn’t such a good idea, and that doing so will cause the invisible hand to engineer boom and bust cycles to siphon large amounts of public money towards private financial institutions again in the future.

On the other hand, the consensus seems to be that it has worked, things are looking up and it cost less than expected, so maybe it was the right thing to do.

I remember reading at the time about the disasterous consequences that were predicted if TARP wasn’t passed – banks would fail, making it very difficult for ordinary businesses (who didn’t cause the crisis) to get credit to grow and/or continue operating.

The obvious answer is to let the banks fail and to bail out these innocent businesses instead – lending to them directly instead of lending to the banks so the banks can lend to the businesses. But figuring out which businesses are good ones to lend money to is a rather complicated and difficult process in itself – one that the government isn’t really set up to do. It makes perfect sense for the government to outsource that work to private institutions (i.e. banks) who were doing it anyway (and not doing altogether too bad of a job at that side of it).

On the other hand, how can we stop this happening again the future? I think the answer is to tie bailout money to the enacting of regulations designed to stop this happening again. In particular, for the current economic crisis it seems like the conflict of interest between credit rating agencies and the issuers of securities was a major cause, and I suspect that well placed regulations there could prevent similar crises.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

The fundamental differences between Windows and Linux

Wednesday, July 14th, 2010

When I started to get deeper into Linux programming, I found it fascinating to learn about the design decisions that were made differently in Windows and Linux, and the history between them.

One example in particular is how dynamic linking is done. Windows dynamic link libraries (DLLs) are compiled and linked to load at a particular address in memory. When a DLL is loaded, the loader inserts the addresses of A DLL can be loaded at a different address (in the case that its preferred address is already in use), but then the loader must relocate it, which is an expensive operation and prevents the DLLs code from being used in other processes. Once loaded, however, code in a DLL is no slower than any other code on the system (calls from one module to another are slightly slower than calls within a module though, since there is a level of indirection involved).

With Linux, on the other hand, the equivalent (shared object files) are compiled to use position independent code, so can be loaded anywhere in memory without relocation. This improves process startup speed at the expense of runtime speed – because absolute addresses cannot be used, in situations where they would otherwise be used the load address must be found and added in.

Another way Linux improves startup speed at the expense of runtime speed is lazy binding of function calls. In a Linux process, a call to a shared library is not normally resolved until the first time it is called. Function pointers initially point to the resolver, and when a function is resolved that pointer is replaced with the found function pointer. This way, the loader doesn’t spend any time resolving functions that are never called.

It makes perfect sense that Linux should sacrifice runtime speed for startup speed given the history of Unix. The first versions of Unix had no multithreading – each thread of execution (process) had its own memory space. So you needed to be able to start processes as quickly as possible. With the fork() system call, a new process could be created by duplicating an existing process, an operation which just involved copying some kernel structures (the program’s data pages could be made copy-on-write). Because process startup was (relatively) light, and because of Unix’s philosophy that a program’s responsibilities should be as limited as possible (and that complex systems should be made out of a number of small programs), processes tend to proliferate on operating systems modelled on Unix to a much greater extent than Windows.

However, this does mean that a program developed with Windows in mind (as a single monolithic process) will tend to run faster on Windows than on Linux, and a program developed with Linux in mind (as many small cooperating processes continually being created and destroyed) will tend to run faster on Linux than on Windows.

Another way in which Linux and Windows differ is how they deal with low memory situations. On Linux, a system called the “OOM killer” (Out Of Memory killer) comes into play. The assumption is that if a machine is running too low on memory, some process or other has gone haywire and is using it all. The OOM killer tries to figure out which process that is (based on which processes are using a lot of memory, and which critical system processes are trusted not to go haywire) and terminates it. Unfortunately it doesn’t always seem to make the right choice, and I have seen Linux machines become unstable after they run out of memory and the OOM killer kills the wrong thing.

Windows has no OOM killer – it will just keep swapping memory to disk and back until you get bored and kill the offending process yourself or reboot the machine. It’s very easy to bring a Windows machine to its knees this way – just allocate more virtual address space than there is physical RAM and cycle through it, modifying each page as rapidly as possible. Everything else quickly gets swapped out, meaning that even bringing up the task manager to kill the program takes forever.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

User code in kernel mode

Monday, July 12th, 2010

Most modern operating systems have a great deal of complexity in the interface between user mode and kernel mode – 1100 syscalls in Linux 2.4.17 and some 400 odd in Windows Vista. This has implications for how security (since all those calls need be hardened against possible attack) and also implications for how difficult it is to learn to program a particular platform (albeit indirectly, since the syscall interface is not usually used directly by application programs).

It would be much better if the system call interface (and the programming API on top of that) was as minimalistic as possible whilst still securely multiplexing hardware and abstrating away hardware differences.

The reason it isn’t is that doing so would make an operating system extremely slow. It takes some 1000-1500 cycles to switch between user mode and kernel mode. So you can’t do a syscall for each sample in a realtime-generated waveform, for example. There are many other ways that an operating system could be simplified if not for this cost. TCP, for example, is generally implemented in the kernel despite the fact that it is technically possible to implement it in userspace on top of a raw IP packet API. The reason is that network performance (especially server performance) would be greatly impacted by all the extra ring switching that would be necessary whenever a packet is sent or received.

A much simpler system API would be possible if user programs could run code in kernel mode – that way they could avoid the ring switch and all the other associated overhead. This was the way things used to be done, back in the days of DOS. Of course, back then every application you used needed to support every piece of hardware you wanted to use it with, an application crash would take down the entire system and there was no such thing as multi-user. We certainly don’t want to go back to those bad old days.

Microsoft’s Singularity OS (as I’ve mentioned before) solves this problem by requiring that all code is statically verifiable, and then runs it all in ring 0. Given how much code performance enthusiasts like I like to write highly optimized but completely unverifiable code, I think it will be a while before memory protection becomes a thing of the past.

But maybe there’s a middle path involving both approaches – unverified code using the MMU and verified code running in the kernel. A user application could make a system call to upload a piece of code to the kernel (perhaps a sound synthesis engine or a custom TCP implementation) and the kernel could statically verify and compile that code.

With a suitably smart compiler, parts of the kernel could also be left in an intermediate form so that when the user code is compiled, the kernel implementations could be inlined and security checks moved outside of loops for even more speed.

Another thing that such a system would make practical is allowing applications to subvert the system calls of less trusted applications.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark

Optimizing by taking advantage of undefined behaviour

Sunday, July 11th, 2010

Undefined behavior doesn’t sound like something you’d ever deliberately introduce into a program’s codebase. Programmers generally prefer their programs’ behaviors to be fully defined – nasal demons are rarely pleasant things.

However, there are sometimes good reasons for adding a statement to your program with undefined behavior. In doing so, you are essentially telling the compiler “I don’t care what happens if control flow reaches this point”, which allows the compiler to assume that control flow will never get to that point if doing so will allow it to better optimize the parts of the program that you do care about. So it can be an optimization hint.

A good way to use this hint is to put it in the failure path of assert statements. In checked/debug builds, assert works as normal (does the test and terminates the application with a suitable message if the test fails) but in release/retail builds assert checks the test and does something undefined if the test fails. The compiler can then skip generating the code to actually do the test (since it’s allowed to assume that it will never fail) and can also assume that the same condition is false in the subsequent code, which (if it’s sufficiently smart) will allow it to generate better code.

GCC has a built-in function for just this purpose: the __builtin_unreachable() function is specified to have undefined behavior if it is ever called, and is actually used in just this way. I think this is really clever, in a slightly twisted way.

  • Reddit
  • Digg
  • Facebook
  • StumbleUpon
  • Twitter
  • Delicious
  • Share/Bookmark