Friday, October 9, 2015

Sabayon and microcodes

Hi everybody. This is the first of new kind of posts on my blog to help Sabayon users (and Linux users in general) to figure out how to fix some issue that I found on my way.
Today I want to share with you a little and simple guide to upgrade microcode in your Sabayon. 
But let's us start from the beginning.

What is microcode?

Intel and AMD microcodes are, citing Debian wiki:
Processor microcode is akin to processor firmware. The kernel is able to update the processor's firmware without the need to update it via a BIOS update.
so to guarantee the system stability and security, you need to keep your CPU microcodes updated.

How do I update my microcodes?

If you have an AMD CPU the microcode are shipped in the linux-firmware package, so you need to do nothing if you update frequently your system, but things get a bit more complex with an Intel CPU (like Haswell).
That is because Intel ucode need to be loaded before the kernel, so you have to do this using the following steps.
The first thing to do consist in generating the microcode cpio archive through iucode_tool (you can find it on sabayonlinux.org repo installing sys-apps/iucode_tool):

root# iucode_tool -S --write-earlyfw=/boot/early-ucode.cpio /lib/firmware/intel-ucode/*
iucode_tool: system has processor(s) with signature 0x000306c3
iucode_tool: Writing selected microcodes to: /boot/early-ucode.cpio

the file early-ucode.cpio should be placed in the initrd of your grub.cfg just before your kernel, but if you put it there directly every time you will regenerate your grub it will be removed.
So the best thing to do is edit the script used from grub-mkconfig.
The file you are looking for is /etc/grub.d/10_linux and you need to change the if clause here reported as follows.

140
141
142
143
144
145
146
147
 if test -n "${initrd}" ; then
    # TRANSLATORS: ramdisk isn't identifier. Should be translated.
    message="$(gettext_printf "Loading initial ramdisk ...")"
    sed "s/^/$submenu_indentation/" << EOF
 echo '$(echo "$message" | grub_quote)'
 initrd ${rel_dirname}/early-ucode.cpio ${rel_dirname}/${initrd}
EOF
  fi

(WARNING: line's numbers reported could change between GRUB 2 versions)
After this we have almost done, so you can simply rebuild your GRUB configuration using:

root# grub-mkconfig -o /boot/grub/grub.cfg

To check if you upgraded correctly your microcode dmesg should be like this:

root#  dmesg | grep microcode
[    6.430637] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x8
[    6.432835] microcode: CPU0 sig=0x306c3, pf=0x10, revision=0x8
[    6.434503] microcode: CPU0 updated to revision 0x1c, date = 2014-07-03
[    6.434511] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x8
[    6.436075] microcode: CPU1 sig=0x306c3, pf=0x10, revision=0x8
[    6.436958] microcode: CPU1 updated to revision 0x1c, date = 2014-07-03
[    6.436987] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x8
[    6.437015] microcode: CPU2 sig=0x306c3, pf=0x10, revision=0x8
[    6.437903] microcode: CPU2 updated to revision 0x1c, date = 2014-07-03
[    6.437912] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x8
[    6.437934] microcode: CPU3 sig=0x306c3, pf=0x10, revision=0x8
[    6.438823] microcode: CPU3 updated to revision 0x1c, date = 2014-07-03
[    6.438830] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x8
[    6.438864] microcode: CPU4 sig=0x306c3, pf=0x10, revision=0x8
[    6.439753] microcode: CPU4 updated to revision 0x1c, date = 2014-07-03
[    6.439760] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x8
[    6.439785] microcode: CPU5 sig=0x306c3, pf=0x10, revision=0x8
[    6.440669] microcode: CPU5 updated to revision 0x1c, date = 2014-07-03
[    6.440682] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x8
[    6.440707] microcode: CPU6 sig=0x306c3, pf=0x10, revision=0x8
[    6.441594] microcode: CPU6 updated to revision 0x1c, date = 2014-07-03
[    6.441601] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x8
[    6.441621] microcode: CPU7 sig=0x306c3, pf=0x10, revision=0x8
[    6.442512] microcode: CPU7 updated to revision 0x1c, date = 2014-07-03
[    6.442557] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba

Remember to check frequently if you have the last microcode updated and don't forget to regenerate your cpio file.
And that's all folks, I hope this could help you to have a more stable system.

Sources:

Friday, June 5, 2015

Calculating Angular Distance

Hi there followers, it's been a while from the last post but here I am again with fresh news.
Some weeks ago I was writing a program for an exam and I thought that sharing with you this code could be a good idea.
This because it's simple and can make easily understand how to fairly share the work between process with Open MPI.

Project Requirements

The goal is to develop a program written in C that calculate the angular distances between a group of stars, and than write as output the distribution of those distances so that could be plotted with Gnuplot.

The angular distance

Quoting Wikipedia:
In mathematics (in particular geometry and trigonometry) and all natural sciences (including astronomy, geophysics, etc.), the angular distance (angular separation, apparent distance, or apparent separation) between two point objects, as observed from a location different from either of these objects, is the size of the angle between the two directions originating from the observer and pointing towards these two objects.
So to calculate the position of two point i and j in the space we can use the following equation to get \( \theta \):

\[\theta_{ij} = arcos \left ( \frac {x_i x_j + y_i y_j + z_i z_j} {\sqrt{ (x_i^2+y_i^2+z_i^2) (x_j^2+y_j^2+z_j^2)} } \right ) \]

The result of this is a number between \( [0, \pi )  \).

Calculating the distribution

We know now how to calculate the angular distance between two points, but our goal is to get a distribution over a set of stars, and we get the parameter K to sample our set of values.
But our huge first problem is the number of operations required because defined \(n\) as the stars' number, we have \( \frac{n(n-1)} {2} \) distances.
So with a large amount of stars, we can easily reach billion of operations.
If we imagine the distances that we need to compute displaced as an upper triangular matrix, we need to split fairly the matrix's elements between our pool of processes.
The idea now is to transform the matrix in an array that concatenate every row of the matrix, in this way we can split the work but we lose a big information. How could we get back the row and the column simply from the index of the elements in the array?
Googling a lot I finally found the solution, even avoiding the two loops, using the following two formulas:
\[I_r =-{ \frac{(-2(n-1) - 1 + \sqrt{ 4 n (n-1) - 8 i - 7} )} {2}}\]
\[I_c = i - (n - 1) I_r + I_r \frac{I_r + 1} {2} + 1\] 
where \( I_r \) is our row index and  \( I_c \) is our column index.
We can now calculate our distribution of distance and this is the output for a set of 119613 stars and 1000 K intervals:
The output was generated in 151.870678 seconds with 8 processors on Intel i7 4700MQ quad core, a really good result.
The resulting speedup is plotted in the following image:
and this is the efficiency of the program:
We can see that with the Hyper Thread technology we obtain a little amount of speedup even if we go over the physical core number, but over 8 processes the efficiency goes down fast on a quad core.

So that's all folks, you can find this program and the example data-set on Github at the following link:
Please let me know if anything isn't clear or wrong, and I will try to correct it until it is. 
So if you linked this post, share, share, share!