Wink Saville’s Blog

September 8, 2009

Using performance counters on x86; pref

Filed under: linux — wink @ 6:34 am

This email from Ingo Molnar gives a simple introduction on how to use pref on an x86 to gain information on system performance.

Do you have an x86 box to test it on?

If yes then perfcounters can be used for _much_ more precise
measurements that you can trust. Do something like this:

perf stat -a --repeat 3 sleep 1

The ‘-a/–all’ option will measure all CPUs – everything: IRQ
context, irqs-off region, etc. That output will be comparable before
your threaded patch and after the patch.

Here’s an example. I started one infinite loop on a testbox, which
is using 100% of a single CPU. The system-wide stats look like this:

# perf stat -a --repeat 3 sleep 1

Performance counter stats for ’sleep 1′ (3 runs):

16003.320239  task-clock-msecs  #     15.993 CPUs    ( +-   0.044% )
94  context-switches            #      0.000 M/sec   ( +-  11.373% )
3  CPU-migrations               #      0.000 M/sec   ( +-  25.000% )
170  page-faults                #      0.000 M/sec   ( +-  0.518% )
3294001334  cycles              #    205.832 M/sec   ( +-  0.896% )
1088670782  instructions        #      0.331 IPC     ( +-  0.905% )
1720926  cache-references       #      0.108 M/sec   ( +-  1.880% )
61253  cache-misses             #      0.004 M/sec   ( +-  4.401% )

1.000623219  seconds time elapsed   ( +-   0.002% )

the instructions count or the cycle count will go up or down,
precisely according to how the threaded handlers. These stats are
not time sampled but ‘real’, so they reflect reality and show
whether your workload had to spend more (or less) cycles /
instructions /etc.

I started a second loop in addition to the first one, and perf stat
now gives me this output:

# perf stat -a –repeat 3 sleep 1

Performance counter stats for ’sleep 1′ (3 runs):

16003.289509  task-clock-msecs  #     15.994 CPUs    ( +-   0.046% )
88  context-switches            #      0.000 M/sec   ( +-  15.933% )
2  CPU-migrations               #      0.000 M/sec   ( +-  14.286% )
188  page-faults                #      0.000 M/sec   ( +-   9.414% )
6481963224  cycles              #    405.039 M/sec   ( +-   0.011% )
2152924468  instructions        #      0.332 IPC     ( +-   0.054% )
397564  cache-references        #      0.025 M/sec   ( +-   1.217% )
59835  cache-misses             #      0.004 M/sec   ( +-   3.732% )

1.000576354  seconds time elapsed   ( +-   0.005% )

Compare the two results:

before:
6481963224  cycles              #    405.039 M/sec   ( +-   0.011% )
2152924468  instructions        #      0.332 IPC     ( +-   0.054% )

after:
3294001334  cycles              #    205.832 M/sec   ( +-  0.896% )
1088670782  instructions        #      0.331 IPC     ( +-  0.905% )

The cycles/sec doubled – as expected. You could do the same with
your test and not have to rely in the very imprecise (and often
misleading) ‘top’ statistics for kernel development.

The IPC (instructions per cycle) factor stayed roughly constant -
showing that both workloads can push the same amount of instructions
when normalized to a single CPU. If a workload becomes very
cache-missy or executes a lot of system calls then the IPC factor
goes down – if it becomes more optimal ‘tight’ code then the IPC
factor goes up.)

(The cache-miss rate was very low in both cases – it’s a simple
infinite loop i tested.)

Furthermore the error bars in the rightmost column help you know
whether any difference in results is statistically significant, or
within the noise level.

Hope this helps,

Ingo

July 5, 2009

Autoconf

Filed under: What I learned today, linux — Tags: , — wink @ 5:48 pm

While starting a protobuf compiler I learned a little about autoconf. First it complains about version the protobuf code was using automake 1.10.1 and I had 1.7.9. so I upgraded to automake using “sudo apt-get install automake1.10″. Of course this upgraded my automake to 1.10.2 which still didn’t work.The solution was to run autoconf from the path/to/protobuf-2.1.0 but that didn’t work until I used “sudo apt-get libtool” to get the latest libtool. This uses the configure.ac and then generated Makefile.in from the Makefile.am.

git – Remote branches

Filed under: scm — wink @ 1:56 pm

Learned that you can manually create remote branches. This is done having the destination refspec be refs/head. Example:git push ../git2 b2:refs/heads/b2The above will push branch b2 to  repo ../git2.I finally got the force flag (-f) do work. I’ve wanted to do a force when I did a rebase –interactive and of a branch and then wanted to backup it up but I’d get an error about it being a non-fast forward merge. By using <src>:<dst> refspec and the -f it seems to work:

git push ../git2 -f b3:b3

Of course I just tried it and it failed:

error: denying non-fast forward refs/heads/me (you should pull first)To ../git2! [remote rejected] me -> me (non-fast forward)

Also, the following makes and interesting pushes:

git push ../git2 *:*git push ../git2 *:refs/heads/git1-backups/*

I need to investigate how useful they might be?

Apple keyboard delete to right key remapping

Filed under: What I learned today, linux — wink @ 1:56 pm

Had some trouble getting the small aluminum keyboard to do a delete to the right. But with the help of this post I got it workings. Basically you need to create a .xmodmap file in your home directory with with the keycode of the key that you want to be Delete in this case 169 is for the “eject” button:

keycode 169 = Delete

Also by adding to .xmodmap:

keycode 133 = Alt_L MetaL

keycode 134 = Alt_R MelaR

You can map the command keys to Alt left and right respectively. You can use the “xev” program to determine the keycodes.

June 13, 2009

Viewing an old version of a file in git

Filed under: What I learned today — wink @ 8:03 am

Use “show” command, but you need to use the full path from the root of the git repo to the file, otherwise you’ll get an error such as below. This same error happens if there is any other error in the parameter, for instance a miss-spelling:

$ git show HEAD:hxy
fatal: ambiguous argument ‘HEAD:hxy’: unknown revision or path not in the working tree.
Use ‘–’ to separate paths from revisions

Anyway, to look at a particular file use can use git log to see the various revisions:

$ git log –pretty=oneline -3 help.c
746c221ad063854e23661f6898c002c8726f5dad git wrapper: also use aliases to correct mistyped commands
277cd4c4bd8cca31395846fc80ea28bf2cd4ddf2 Merge branch ‘ar/autospell’
f0e90716d47b429284702b75425a247c9fc41adb Add help.autocorrect to enable/disable autocorrecting
$ git show f0e90716d47b429284702b75425a247c9fc41adb:help.c

To see the current version you’d could use the the first entry.


$ git show 746c221ad063854e23661f6898c002c8726f5dad:help.c

To see the previous version use the second sha1:


$ git show 277cd4c4bd8cca31395846fc80ea28bf2cd4ddf2:help.c

I wonder if there is a simple syntax to get a particular revision such as:


$ git show REV^:help.c

May 30, 2009

Full screen mode on Mac os x X11 – command-option-A to switch

Filed under: What I learned today — wink @ 6:35 am

When in X11 full screen mode use Command-option-A to switch to back to mac apps. Also command-option-esc will bring up the Mac task list and allow you to switch to other tasks.

April 19, 2008

linux – Excessive hard disk activity (or how to execute something while booting)

Filed under: linux — wink @ 11:01 am

A common problem encountered with laptop is that there is excessive activity due to the heads being loaded and unloaded frequently as described here. The solution for my HP zv5000 laptop was to use hdparm to disable advanced power management:

hdparm -B 255 /dev/sda

Since this needs to be performed every time the system boots you need to figure out a good place for the code. For Ubuntu I chose to add it to /sbin/setup.sh which is a script exectued by the The solution I used with Ubuntu was to add the above line to /sbin/setup.sh. In my case /sbin/setup.sh didn’t exist so I created it, be sure it’s executable.

When I changed my laptop to use Fedora I found the same problem, but Fedora doesn’t exectue /sbin/setup.sh instead I found the suggested mechanism was to add the code to file /etc/rc.d/rc.local.

March 16, 2008

scm – git svn connect

Filed under: linux, scm — wink @ 9:45 pm

The following allows you to reconnect a local clone of a remote svn repo assuming a git repo exists. In my case I have a backup of the remote svn repo but its a pure git repo without any git-svn meta data. Steven Walter provided the basic instructions here.

lcl ~/ $ git clone git://srv/amc.git amc
lcl ~/ $ cd amc
lcl ~/amc $ git svn init -s http://async-msgcomp.googlecode.com/svn
lcl ~/amc $ rm -rf .git/svn
lcl ~/amc $ cp .git/refs/remotes/origin/master .git/refs/remotes/trunk
lcl ~/amc $ git svn fetch

At this point a git svn rebase should indicated “Current branch mastger is up to date.”

March 14, 2008

git – workflow with remote svn repositories

Filed under: programming, scm — wink @ 11:11 am

I’m going to try a new git-svn workflow. Previously I did a git svn clone and also created a backup on my backup server as a remote. So pictorially something like this:

    local-git-svn-clone
           /       \
          /         \
         /           \
remote-svn            backup-server

This worked OK but I’ve made mistakes in the local-git-svn-clone and have had to start all over because things got out of sync. Most often this would happen if I merged into the master branch pushed to the backup-server than then did a “git svn rebase”. I would end up not being able to do any more pushes to the backup-server.

To try to reduce the possibility of mistakes I’m going to try separate repos. So I first. cloned the svn repo as normal:

<local>$ git svn clone -s svn+ssh://wink@<remote-svn-rep>/<path to repo> <local-git-svn-clone>

Then I made a local clone of local-git-svn-clone:

<local>$ git clone local-git-svn-clone local-clone

Next ssh into my backup-server and create a bare shared repo.

<local>$ ssh wink@<backup-server>
<backup-server>$ cd <git-repos>
<backup-server>$ mkdir <backup-repo>
<backup-server>$ cd <backup-repo>
<backup-server>$ git --bare init --shared
<backup-server>$ exit
<local>$

Now back on my local machine I push the local-git-svn-clone repo to the backup repository.

<local>$ cd <local-clone>
<local>$ git remote add backup git://<backup-server>/<backup-repo>
<local>$ git push --repo=backup --all

So at this point <local-clone> points at <local-git-svn-clone> and <backup-repo> which I don’t want. What I want is <local-clone> to just point at <backup-repo>. There may be a simpler way to do this, but I choose to actually delete <local-clone> and create it anew from <backup-repo>.

<local>$ cd ..
<local>$ rm <local-clone>
<local>$ git clone git://<backup-server>/<backup-repo> <local-clone>

So now I have two separate repos on local. <local-clone> connected to <backup-server>/<backup-repo> and <local-git-svn-clone> connected to the <remote-svn-repo>/<path to repo>.

    local-clone    << git pull >>    local-git-svn-clone
           /                                      \
          /                                        \
         /                                          \
back-repo                                          backup-server

Without the direct connection between , but since they are both based on the svn repo I can easily pull local-clone from local-git-svn-clone.

With this configuration you work on branches in local-clone, don’t work on master, the goal is to keep local-clone master exactly the same as local-git-svn-clone. If you don’t do this it will you’ll see trapezoidal commits and things get confusing.

So the work flow becomes:

local-clone$ git checkout -b x
local-clone$ hack
local-clone$ git commit (or git gui)
local-clone$ test
local-clone$ repeat more hack/commit/test
local-clone$ git push --all

So you’ve been working a while and periodically pushing to your back-repo to backup local-clone. Eventually you’ll want to commit the work you’ve done. To do this you’ll pull the changes from local-clone x branch to local-git-svn-clone, svn rebase, test and svn dcommit.

local-git-svn-clone$ git pull <local-clone> x:master
local-git-svn-clone$ git svn rebase
local-git-svn-clone$ test
local-git-svn-clone$ git svn dcommit

If the git svn rebase pulled in a lot of changes you may want to pull these over to local-clone if there and hack/test/commit then back to the above. Eventually you’ll do the svn dcommit.

The last step is to get the changes in local-git-svn-clone into local-clone and push them to backup-repo.

local-clone$ git pull <local-git-svn-clone>
local-clone$ git branch -D x
local-clone$ git push

Of course you don’t need to delete the branch x but all of those changes are now in the local-clone master so they aren’t needed.

March 10, 2008

Linking – How to link 32bit and 64bit x86 code into one image

Filed under: linux, programming — wink @ 11:05 pm

Learned something new from TJ over at Codegen today, he solved a problem where we needed to have 32bit code linked with 64bit code but the linker wouldn’t do it. Apparently this use to work without doing anything, but with the latest linker (ld) code it doesn’t. TJ figured out all that needed to be done was use objcopy to convert the 32bit format to 64bit format:

objcopy -O elf64-x86_64 32bit.o 64bit.o

One other noteworthy element to determine the output formats that objcopy supports use objcopy –info or objcopy –help

wink@ic2d1:$ objcopy --info
BFD header file version (GNU Binutils for Ubuntu) 2.18
elf64-x86-64
 (header little endian, data little endian)
  i386
elf32-i386
 (header little endian, data little endian)
  i386
a.out-i386-linux
 (header little endian, data little endian)
  i386
efi-app-ia32
 (header little endian, data little endian)
  i386
efi-app-x86_64
 (header little endian, data little endian)
  i386
elf64-little
 (header little endian, data little endian)
  i386
elf64-big
 (header big endian, data big endian)
  i386
elf32-little
 (header little endian, data little endian)
  i386
elf32-big
 (header big endian, data big endian)
  i386
srec
 (header endianness unknown, data endianness unknown)
  i386
symbolsrec
 (header endianness unknown, data endianness unknown)
  i386
tekhex
 (header endianness unknown, data endianness unknown)
  i386
binary
 (header endianness unknown, data endianness unknown)
  i386
ihex
 (header endianness unknown, data endianness unknown)
  i386

               elf64-x86-64 elf32-i386 a.out-i386-linux efi-app-ia32
          i386 elf64-x86-64 elf32-i386 a.out-i386-linux efi-app-ia32
               efi-app-x86_64 elf64-little elf64-big elf32-little elf32-big
          i386 efi-app-x86_64 elf64-little elf64-big elf32-little elf32-big
               srec symbolsrec tekhex binary ihex
          i386 srec symbolsrec tekhex binary ihex
Older Posts »

Powered by WordPress