Cache & Exponents

Uncategorized No Comments »

Yesterday I configured cacti to monitor PostSharp servers. After one day of operation, I was stroked by this graph. The green area shows disk I/Os per second.

image

The peek corresponds to a system reboot. What is striking here is the look of the curve: it is approximately an exponential decay (with a negative exponent):

 read(t) ~ b * [ (WS - R) + c * exp(- lambda * t) ]

where WS is the data working set (the amount of data your server need for normal operations), R is the amount of RAM available for cache, and b is proportional to the read flow and c and lambda are some cache filling rates.

This kind of curse is called an exponential decay.

Note that it takes a fair amount of time for the cache to be full (about 4 hours on this server). When the cache is full, there is a nearly constant read flow, about 20 KB/s here.

Should we deduce from this graph that it would not pay off to add much RAM? that the relationship between RAM and performance is an exponential decay as well?

Don’t go so fast! First, we have to understand where does this exponential decay come from.

At any time, the server needs to read some data. Suppose the probability that some data is required is uniform. The probability that the data is cached is directly proportional to the size of the cache. Therefore, the amount of data I have to read from disk is proportional to the amount of non-cached data. So we must explain why the amount of non-cached data looks like an exponential decay.

The differential equation of dynamics with exponential decay is:

image

Does it confirm our hypothesis? Yes! It means that the cache increase rate is proportional to the amount of non-cached data. This is exactly our initial hypothesis.

That are the maths. But what about reality? Can we believe the hypothesis that “some data is required at a given time is uniform”. Not at first sight, but if we look twice it is probable. Of course, some data is much more frequently required than other. This seems to break our assumption. But remember that we just consider disk cache, which is the last-resort cache. All executable code is already in memory; applications have their own cache (MySql, ASP.NET, Apache). So it is plausible that the remaining data has uniform probability of being accessed.

When something unusual happens (for instance some maintenance), the nice curve is disturbed, cache is filled with something less useful (or less useful at long term), and the exponential decay restarts as soon as the maintenance task has finished!

Interesting discussion around a simple graph, isn’t it?

Back from Warsaw (Poland) and Prague (Czech Republic)

.net 2 Comments »

Ouf! I have given 3 presentations last 4 days, two in Warsaw at ZineDay 2008 (an event organized by a community of bloggers), the other in Prague, 30 km from home only.

Warsaw

There were 3 technical sessions in Warsaw and I gave 2 of them. The other one was delivered by Andras Belokosztolszki, software architect for SQL products at RedGate (and btw a Hungarian with a Polish name living in London).

I was seconded by Jakub Binkowski and we could deliver a real theater play together: he supposed to be new to AOP and asked questions, I answered. The result was great, I think. And much more funny for the audience! Ideally, I should do it this way every time…

The mini-conferences ended with a contest where 6 Polish open-source projects were competing. I loved the idea. Open-source programming is a very lone activity; electronic communication does not replace real contacts. It was great to bring people together and to be able to socialize a bit!

The winners of the contest were:

  • Tytan.Net, a “power tools” toolbar for Visual Studio,
  • NGinn, a workflow engine based on Petri networks.
  • Log4PostSharp, a project I have been following and supporting for a long time, using PostSharp to emit highly optimized code to use log4net from custom attributes.

Prague

It was the first time I presented PostSharp in what is now my home country. I got an audience of maybe 50 persons, which is quite good by standards of other countries for events of this (small) importance.

The talk was in Czech. Although it is not my mother tongue, I master it quite well, especially the informal language, and the result was that it was much more funny than when I present in English. I even think that the fact that Czech is not my mother tongue played in my favor since I could take some licenses a Czech could not. So the first, theoretical, part of the show was great, but I think the second one was done better in Warsaw thanks to Jakub.

I also took the opportunity of this session to announce the release of PostSharp 1.0 RTM. I think it was great that I could make this important announcement in the home country of the product — and it matched fairly PostSharp’s calendar.

What a busy week! Tomorrow I go to Austria for a meeting with guys from Spring.NET…

-gael

Political Repression. Not in Beijing.

politics 1 Comment »

Political repression in Denver, USA, during the Democrat National Convention. Unbelievable.

e-Book: How to Survive the Multicore Software Revolution (or at Least Survive the Hype)

.net No Comments »

A good e-book from vendors of a parallel computing toolkit. Marketing material, but of high value for everyone.

e-Book: How to Survive the Multicore Software Revolution (or at Least Survive the Hype)

A Cloning Pattern

.net 5 Comments »

Object cloning are one of the patterns we find in most software projects. It seems simple, so we easily run into a trivial implementation. But as code gets more complex, the cloning implementation rapidly gets larger and larger — and ugly. To keep cloning simple, I forced myself to follow a simple design pattern. Here is it:

   1:  class Cloneable : ICloneable
   2:  {
   3:     public object Clone()
   4:     {
   5:      Cloneable clone = this.MemberwiseClone();
   6:      this.CopyTo( clone );
   7:      return clone;
   8:     }
   9:  
  10:     protected virtual void CopyTo(Cloneable clone)
  11:     {
  12:        // Children should implement this method to
  13:        // clone cloneable properties.
  14:     }
  15:  }

The advantage of using MemberwiseClone is that I easily create a new instance. Additionally, it is really fast (the Rotor implementation uses memcpy). No need of reflection. It actually makes a shallow copy, so a big part of the job is already done:

  • We have a shallow copy of fields of value types.
  • Immutable reference types (like string) do not need to be cloned.

The goal of the CopyTo method is to take care of fields requiring special attention. The design pattern says that every class should call base.CopyTo() and make a deep copy of the fields it defines, for instance:

   1:  public class Address : Cloneable
   2:  {
   3:    // Immutables.
   4:     public string AddressLine1, AddressLine2,
                        AddressLine3, Zip, City;
   5:     // Value type.
   6:     public int CountryID;
   7:  
   8:     // No CopyTo: a shallow copy is sufficient.
   9:  
  10:  }
  11:  
  12:  public class Party : Cloneable
  13:  {
  14:       public int ID; // Value-type.
  15:       public string FirstName, LastName;  // Immutables.
  16:       public Address LegalAddress; // Cloneable.
  17:  
  18:      protected override void CopyTo(Cloneable clone)
  19:      {
  20:         base.CopyTo(clone);
  21:        ((Party) clone).LegalAddress =
                 (Address) this.LegalAddress.Clone();
  22:      }
  23:  }
  24:  
  25:  public class Customer : Party
  26:  {
  27:       public Address DeliveryAddress;
  28:  
  29:      protected override void CopyTo(Cloneable clone)
  30:      {
  31:         base.CopyTo(clone);
  32:        ((Customer) clone).DeliveryAddress =
                (Address) this.DeliveryAddress.Clone();
  33:      }
  34:  
  35:  }

This may looks trivial, and indeed it is, but it works so well!

Implementing CopyTo() Automatically

You could expect me on that point. CopyTo is basically plumbing code no one wants to write. There should be a way to implement it automatically.

Can you use PostSharp for this? Of course! The PostSharp implementation of this pattern is actually a part of the sample

PostSharp.Samples.Librarian, a sample released to the public domain (and packaged with PostSharp).

It generates code to clone cloneable fields, and raise a build-time error when it does not know how to cope with that field type. I won’t comment further on that until you ask; please refer to the sample.

However, I don’t use PostSharp for this pattern. The reason is that the PostSharp-based solution is implemented using the low-level APIes and I don’t want to use them unless it is really necessary. And since I don’t have any special requirement (like performance or CAS), I use… System.Reflection.

There is an old adage telling that when someone has a hammer, everything looks like a nail. I try not to fall in that trap! The implementation simply iterate over all fields (or properties) of the type, reads them from the source object and assigns the value to the clone.

Cloning Trees

What is a little more difficult is to clone trees when children have a relationship to the parent. I have defined an interface:

   1:  public interface ICloneableTreeItem : ICloneable
   2:  {
   3:       ICloneableTreeItem Clone(object parent);
   4:  }

The implementation pattern is of course much similar.

Summary

Simple patterns keep simple things simple, and Reflection is not Evil!

Wordpress Themes by Natty WP.
Images by koop viagra desEXign.