2. February, 2008
2. February, 2008
in
»
»
by Michael Neumann

Have you ever wondered why operating system kernels are compiled without full compiler optimizations turned on? The reason is that it’s impossible to implement proper threading in C/C++ in a library, because the execution model of C/C++ is single-threaded. If the compiler doesn’t know about threads, it might optimize a global variable access into a register access and if now another thread writes to that global variable we have a race. That’s just one example what can happen. A good introduction into the problem is given here (in German) or in the video Getting C++ Threads Right by Hans Boehm.

The next version of C++ called C++0x will include approaches to overcome this limitation. That would be a nice addition to the C standard as well, as C is used quite extensivly in systems programming where this matters even more.

If you are into high-performance number crunching then you should consider Unified Parallel C (UPC). It unifies both message passing (as used by MPI) and the shared memory model (as used by OpenMP).

What I am dreaming of is a combination of features from UPC (unified message passing/shared memory), Cyclone (abstract data types, region analysis, fat pointers), C (performance) and some concepts from D (modules, templates, closures). I’d call this language ASYL - Advanced Systems Language.

24. October, 2007
24. October, 2007
in
»
by Michael Neumann

As a C programmer I often used the int type without thinking too much about whether it is an unsigned integer or not. Take indices as example. They usually can’t be negative, nevertheless I regularily use int for them (int is signed by default).

From my old assembly days I know an optimization trick which comes into play when you want to divide by a power of two. This can be optimized by using a bit shift right operation. In the same way you can speed up multiplications by using bit shift left.

In my code I always write “x / 2” instead of “x » 1” for readability reasons. And I always hoped that the compiler is clever enough to do this optimization. Is the compiler really clever enough? Let’s see what the compiler generates:

;
; %eax contains the value of "i"
;

; C code: (int)i / 2
movl %eax, %edx
shrl $31, %edx
addl %edx, %eax
sarl %eax

; C code: (unsigned int)i / 2 
shrl %eax

You see that in both cases the gcc compiler generates a bit shift operation instead of an expensive division. But you can also see that for signed integers it generates three operations more than for unsigned integers. While I couldn’t measure the performance improvements in my algorithms (because memory is the bottle neck here), I use unsigned int whenever possible.

23. September, 2007
23. September, 2007
in
»
»
by Michael Neumann

Every real programmer should definitively know C. It’s a nice (arguable), small, and for sure understandable language which runs on most if not all machines (or at least a cross-compiler exists). Great operating systems like Linux or BSD are written in C. Languages like Ruby or Python are written in C as well. So what about C++?

Well, C++ is a really big beast! It has a lot of features not found in C:

  • Strong(er) typing (I think C99 has this as well)
  • Classes and namespaces
  • Templates
  • Exceptions

But well, as I said, C++ is big, and I heard someone saying that there is not even one compiler around that implements every little detail of C++. Uh, if there is not even one compiler that fully supports C++, how can there be any one guy who understands every little detail of C++? Except Bjarne of course, the creator :).

While C++ has a lot of features, it misses something very important: A garbage collector! That’s an absolute MUST HAVE for any real application.

Another big annoyance in my opinion in C++ is that you usually split your classes into a header (.h) and an implementation file (.cc), which doesn’t help readability.

If you use CplusRuby you get everything that C++ can do, with plain C and Ruby, plus a garbage collector, and a lot of more features. In the next version, I’ll implement templates, which is something that I really need to improve performance. So stay tuned.

21. September, 2007
21. September, 2007
in
»
by Michael Neumann

In my last article I wrote about using Ruby and C to implement a high-performance pulsed neural net simulator. The first result is a library called CplusRuby which makes it easy to mix Ruby and C. Take a look at the README and/or at the following example:

require 'cplusruby'

class NeuralEntity < CplusRuby
  property :id
end

class Neuron < NeuralEntity
  property :potential,        :float
  property :last_spike_time,  :float
  property :pre_synapses,     :value

  method_c :stimulate, %(float at, float weight), %{
    // this is C code
    selfc->potential += at*weight;
  }

  def initialize
    self.pre_synapses = []
  end
end

# generate C file, compile it and load the .so
CplusRuby.evaluate("inspire.cc", "-O3", "-lstdc++")

if __FILE__ == $0
  n = Neuron.new
  n.id = "n1"
  n.potential = 1.0
  n.stimulate(1.0, 2.0)
  p n.potential # => 3.0
end

Note that the crux of CplusRuby is high-performance. The properties form a C structure which is attached to the Ruby object. The C functions can access those values directly, and C functions are itself properties, as such you can call other C method-functions directly without going through Ruby, which is sloooow! On the other hand, you can access everything from Ruby as well. Of course all garbage collecting stuff is generated for you automatically!