Posts

Using the AVX instruction set to boost performance

Image
The AVX instruction set uses CPU registers to perform SIMD (Single Instruction Multiple Data) operations, which can be used to significantly speed up mathematical operations. I recently decided to create a digital filter in C++, and starting with the basics I came across a Finite Impulse Response (FIR) filter. Mathematically a FIR filter outputs a weighted sum of the most recent input values of the signal. The mathematics of a FIR filter are outlined  here . In practice, we typically work on sections of a signal. This is quite simply because we can not hold the entire signal in RAM. Consider the following signal which has been split into three chunks each of size 6,                                                        $$ [012123][123332][123342] $$ and the following filter $b = [1,2]$. In the routines discussed in this blog the a...

Information Entropy

In the field of Information Theory, we can define the information conveyed $I(E)$ by the occurrence of an event $E$ as $$I(E) = \log \frac{1}{p(E)},$$ where $p(E)$ is the probability of the event $E$. Note that if the event is unlikely then the information gained is large. Suppose that we have an information source $X$, which can be thought of as a discrete random variable. $X$ can take on many "states" $\{x_i\}$. We can define the entropy of the system as $$H(X) = \sum_i^n  p(x_i)I(x_i),$$ where $n$ is the number of states that $X$ can take. An example of $X$ is an alphabet. A qualitative description of the entropy of an information source is a measure of its unpredictability. We can see this by observing the following: If the probabilities of the states of the source are uniform the entropy is maximised. That is, when we have no prior information about the likelihood of each state we expect the entropy of the information source to be large. We can prove this f...

Move Semantics

In this post we are going to take a look at move semantics. Move semantics rely on the concept of rvalues, which were introduced in C++11. First we must make the distinction between lvalues and rvalues. lvalues are called as such because they have traditionally appeared on the left hand side of an assignment operator and designate an object (among other things). rvalues are called as such because they have traditionally appeared on the right hand side of an operator and typically designate temporary objects (possibly other things). How do we refer to such things in C++? Like so... X & // lvalue reference X & & // rvalue reference What are the uses of such things? One of the main ramifications of rvalue references is move semantics. What this allows us to do is create objects from temporary objects without having to make a deep copy. # include < iostream > # include < list > class BigVec { private : int m_size ; doub...

Static Objects

Static variables in C++ are initialised once and then exist for the lifetime of the programme. Once they have been initialised they can be referred to by using the variable name they were initialised with. In the following code we can see a simple example of the use of static variables. # include < iostream > # include < list > class Base { public : Base ( ) { } ; void foo ( ) ; } ; std :: list < Base * > & thing ( Base * bp ) { static std :: list < Base * > p ; if ( bp ) p . push_back ( bp ) ; return p ; } class Bar { public : Bar ( Base * b ) { thing ( b ) ; } } ; static Bar my_foo ( new Base ( ) ) ; int main ( ) { auto mods = thing ( nullptr ) ; std :: cout < < mods . size ( ) < < std :: endl ; // returns 1 return 0 ; } The first time the function 'thing' is called is via the 'Bar' constructor, in which the sta...