Sunday 14 December 2014

Twenty years of Skidmarks

Lately I've been digging through the old Skidmarks archives, and I came across this wee gem from 1993, no doubt written with lots of help from Simon:

Function.q hite {di.q,dj.q,oset.l}
  UNLK a4
  MOVE.l d2,a0
  MOVE.l d1,d2:SWAP d2:EXT.l d2:ASL.l #7,d2:ADD.l d2,a0
  MOVE.l d0,d2:SWAP d2:EXT.l d2:ASL.l #1,d2:ADD.l d2,a0

  MOVEM (a0)+,d2-d3 ;d0-d1 xy d2-d5 p0-p3
  LEA 124(a0),a0:MOVEM (a0)+,d4-d5
         MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d5  ; x. y.p3
  NOT d0:MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d4  ;-x. y.p2
  NOT d1:MOVE d0,d6:MULU d1,d6:SWAP d6:MULU d6,d2  ;-x.-y.p0
  NOT d0:           MULU d1,d0:SWAP d0:MULU d3,d0   ; x.-y.p1
  ADD.l d2,d0:ADD.l d4,d0:ADD.l d5,d0 ;total
  LSR.l#6,d0:RTS
End Function

For those not quite brave enough to decipher the 68000 assembly, here's what a strictly literal translation might be:

float Height(float x, float y, short *heightField){
  //__asm{...}
  heightField += int(x) * 64;
  heightField += int(y);

  short height2 = *heightfield++, height3 = *heightField++;
  heightField += 62; short height4=*heightfield++, height5 = *heightField++;
  float result5 = frac( x) * frac( y) * height5;
  float result4 = frac(-x) * frac( y) * height4;
  float result2 = frac(-x) * frac(-y) * height2;
  float result0 = frac( x) * frac(-y) * height0;
  float result = (result0 + result2 + result4 + result5);
  return result / 64;
}

The motivation is that I've been working towards a new version for mobile devices, with a working title of "Super Skidmarks 2000" (hashtag #SS2K)

Here's what the modern version of that same function looks like, this time in C++ :

float SKTrack::GetHeight(float axisI,float axisJ)const{
  int fi=(int)floor(axisI);
  int fj=(int)floor(axisJ);

  if(fi<0||fi>=63){
    return 0.0f;
  }
  if(fj<0||fj>=63){
   return 0.0f;
  }
  int index=fi+fj*64;
  float v0=HeightField[index];
  float v1=HeightField[index+1];
  float v2=HeightField[index+64];
  float v3=HeightField[index+65];

  float s=axisI-floor(axisI);
  float t=axisJ-floor(axisJ);

  float v01=v0*(1.0f-s)+v1*s;
  float v23=v2*(1.0f-s)+v3*s;

  float height=v01*(1.0f-t)+v23*t;
  return height;
}


As always, any questions / comments, or suggestion for a better name etc, please leave a comment below!

Saturday 29 November 2014

Why he vertically aligns his code (And why you shouldn't)

Over on Terence Eden's blog, the latest post is about vertically aligning code : https://shkspr.mobi/blog/2014/11/why-i-vertically-align-my-code-and-you-should-too

The "bad" example looks like this:

Which is then "fixed" to make it look like this :


Just for comparison, I typed it into my regular text editor:


The point being, because I'm using a well designed syntax highlighting where the numbers (green) contrast with the operators.  If you so choose, you can visually inspect just the green numbers and just as easily spot the outlier.

(Pro-tip: To concentrate on just one color, defocus your eyes slightly by staring "through" the plane of the monitor to engage your eye's cone cells.  With a little practice, you'll find yourself doing this automatically when you want to focus on the structure of the code instead of the details.  For best results, you might need to make the glyphs larger on screen....)

Note too, how the combination of proportional font and camelCase instead of under_scores keep the code density onscreen the same, but the individual glyphs appear larger in-place.

My code editor also uses syntax highlighting to hint the kerning.  So for example, the kerning around the equals sign and the semi-colon are particularly loose to aid in their recognition. Similarly, the single space character (' ')  has a width 50% larger than would be used for normal paragraph text.

But here's the big change that Terence missed, I've sorted all the variable declarations alphabetically to ensure there are no duplicates.  This is a zero-cost policy that can simplify merges and conflict resolution when multiple variables (possibly duplicate) have been added upstream.

Coding Atoms

The bigger problem is the coding atom is the line-of-code.

Lets take another code example from Terence's blog post, this time a function declaration :

extern int SomeDemoCode(int fred,
                        int wilma);

That's an atom right there - you can't split that up without changing its meaning. Watch what happens if I try to add a parameter in an excess white-space environment:

extern int SomeDemoCode(int fred,
+                       int barney,
                        int wilma);

The diff splits our (atomic) function signature across 3 lines, exposing us to problems where a git merge might accidentally succeed, when really we need it to flag a merge conflict.

(For a real world case of how bad automatic merging can be, take a look at the Goto Fail Bug)

Now compare if everything had been on the same line, the diff would look like :

-extern int SomeDemoCode(int fred, int wilma);
+extern int SomeDemoCode(int fred, int barney, int wilma);


TL;DR: Using whitespace to control your code presentation is a hack from the '70s.. get a better editor.

p.s. Some formatting edits have been made to make this post clearer.

Friday 12 September 2014

Wi-Fi in Schools

A friend of mine asks :

OLPC Class - Mongolia Ulaanbaatar
Question : What's the effect on the human body, of 20 children in a classroom, each downloading a 3 minute youtube video over Wi-Fi?

An excellent question!


As with all good science, let's start with an experiment.  I happen to have a 3 minute HD video on my network, so I can time how long it takes to copy across to my laptop:

missingbytes:$ time copy /NetworkDrive/HDVideo.mp4 .
real   0m6.550s
user   0m0.001s
sys    0m0.116s

So a single 3 minute video (3:19 to be precise) will use about 6.5 seconds of Wi-Fi time to copy.

With 20 students, and rounding up a little to account for congestion..

... lets call it 200 seconds of Wi-Fi activity total.

Transmit power

The transmission power for Wi-Fi signals is heavily regulated in the EU, the US and also in New Zealand where I'm performing the test.

The maximum 2.4-GHz transmission power is regulated by law, so lets assume it's 20dBm = 100mW = 0.1W ( source )

As we all learnt when we were in school, a watt is a joule per second, so 200 seconds at 0.1W is 20J.

Now we know that a class room of children downloading a youtube video results in 20 joules of microwave energy being emitted from the Wi-Fi router's antenna.

A brief diversion : Ionizing and Non-Ionizing radiation



Electromagnetic radiation forms a spectrum, from low frequency and radio waves, up through the microwaves, visible light, X-rays and on to gamma rays which have very high frequencies indeed.

Those high frequencies are characterized as ionizing, they're very dangerous to humans and their ability to cause DNA damage and ultimately cancer is well known. This is the reason why we need to be so careful around medical/dental imaging devices, and need to take precautions such as wearing sunscreen and polarized sunglasses when we're outdoors on a sunny day.

It's not necessarily the amount of energy, it's more the frequency that's the problem.  This high frequency ionizing radiation quite literally has the ability to rip electrons off their atoms.  It's these "ions" which go on to cause damage to biological systems.

By contrast, the lower frequency non-ionizing radiation (such as used in Wi-Fi, or FM radio) doesn't have the same ability to affect us in this way.

By itself, non-ionizing radiation can only cause heating in biological systems. Indirectly, it's this heating which slows down or speeds up chemical reactions and/or signalling within the cell, and it's these secondary effects which has the potential to cause problems.

Intuitively, this is why the 1000 watt microwave oven in your kitchen makes food super hot in a few minutes using microwave energy, but it doesn't actually make your food radioactive.  (You'd need an X-Ray oven for that!)

Anyway, lets continue, we've got 20 joules remember?

Absorption


Now we need to make a pretty unrealistic assumption. Suppose that the entirety of those 20 joules of energy was somehow absorbed by one child.  Of course, this can't happen in the real world for two fairly obvious reasons:

  • A router transmits energy in all directions.  For all the energy to be absorbed by the child, the router would somehow need to be inside the child.
  • Microwave energy interacts only weakly with the human body.  That's one of the great benefits of Wi-Fi, it can pass right through walls and ceilings and straight through you and me.

But just for fun, lets continue on anyway and figure out what would happen if all of those 20 joules were absorbed by one child.

An average 6 year old child weighs about 22 kilograms.  (Of course, my 4 year old son also weighs 22 kilograms, but that's a blogpost for another day!)
The human body is about 65% water, so lets consider 14 kilograms of water.

The specific heat capacity of water is 4.18 J / gK

So we have 20 J / (14,000 g) / (4.18 J / gK) = 0.00034 K = 0.0004 °C
(That's 0.4 millikelvin for all you geeks out there.)

Answers!

So there we have it, even with a wildly exaggerated assumption:

Answer : A classroom of children, all downloading a 3 minute youtube clip over Wi-Fi yields a maximum biological heating due to 2.4GHz microwave radiation of 0.0004 °C.

(0.4 millikelvin is about twice as small as it's possible to measure using a precision thermometer.)

Conclusion


We shouldn't really be too surprised.  Wi-Fi signals are incredibly weak. Consider this, those 20 joules of microwave radiation is the same amount of chemical energy contained in one thousandth of a teaspoon of sugar.

There's no way to prove scientifically that microwave radiation from Wi-Fi is safe in the human body. Science doesn't work that way. You can't prove a negative.

But we can try and make smart choices about tiny risks.


For example, the exposure from a banana is about 0.1 μSv of harmful ionizing radiation because of their high quantities of naturally occurring radioactive potassium.

Yet who thinks twice about giving bananas to kids in schools?

Thoughts, questions or especially corrections?  Please feel free to leave a comment down below!