Monday April 21, 2008 | The Good, the Blog & the Ugly Tim Cook's Weblog |
Comparing the UltraSPARC T2 Plus to Other Recent SPARC ProcessorsUpdate - now the UltraSPARC T2 Plus has been released, and is available in several new several Sun servers. Allan Packer has published a new collection of blog entries that provide lots of detail. Here is my updated table of details comparing a number of current SPARC processors. I can not guarantee 100% accuracy on this, but I did quite a bit of reading...
Footnotes Glossary
References:
What Drove Processor Design Toward Chip Multithreading (CMT)?I thought of a way of explaining the benefit of CMT (or more specifically, interleaved multithreading - see this article for details) using an analogy the other day. Bear with me as I wax lyrical on computer history... Deep back in the origins of the computer, there was only one process (as well as one processor). There was no operating system, so in turn there were no concepts like:
What am I getting at? Well, let me pick out a few of the advances in computing, so I can explain why interleaved multithreading is simply the next logical step. The first computer operating systems (such as GM-NAA I/O) simply replaced (automated) some of the tasks that were undertaken manually by a computer operator - load a program, load some utility routines that could be used by the program (e.g. I/O routines), record some accounting data at the completion of the job. They did nothing during the execution of the job, but they had nothing to do - no other work could be done while the processor was effectively idle, such as when waiting for an I/O to complete. Then muti-processing operating systems were developed. Suddenly we had the opportunity to use the otherwise wasted CPU resource while one program was stalled on an I/O. In this case the O.S. would switch in another program. Generically this is known as scheduling, and operating systems developed (and still develop) more sophisticated ways of sharing out the CPU resources in order to achieve the greatest/fairest/best utilization. At this point we had enshrined in the OS the idea that CPU resource was precious, not plentiful, and there should be features designed into the system to minimize its waste. This would reduce or delay the need for that upgrade to a faster computer as we continued to add new applications and features to existing applications. This is analogous to conserving water to offset the need for new dams & reservoirs. With CMT, we have now taken this concept into silicon. If we think of a load or store to or from main (uncached) memory as a type of I/O, then thread switching in interleaved multithreading is just like the idea of a voluntary context switch. We are not giving up the CPU for the duration of the "I/O", but we are giving up the execution unit, knowing that if there is another thread that can use it, it will. In a way, we are delaying the need to increase the clock rate or pipe-lining abilities of the cores by taking this step. Now the underlying details of the implementation can be more complex than this (and they are getting more complex as we release newer CPU architectures like the UltraSPARC T2 Plus - see the T5140 Systems Architecture Whitepaper for details), but this analogy to I/O's and context switches works well for me to understand why we have chosen this direction. To continue to throw engineering resources at faster, more complicated CPU cores seems to be akin to the idea of the mainframe (the closest descendant to early computers) - just make it do more of the same type of workload. See here for the full collection of UltraSPARC T2 Plus blogs Posted by timc ( Apr 09 2008, 06:00:00 AM PDT ) Permalink Comments [2]Utilization - Can I Have More Accuracy Please?Just thought I would share another Ruby script - this one takes the output of mpstat, and makes it more like the output of mpstat -a, only the values are floating point. I wrote it to process mpstat -a that I got from a customer. It can also cope with the date (in Unix ctime format) being prepended to every line. Here is some sample output:
The script is here. Interestingly, you can use this to get greater accuracy on things like USR and SYS than you would get if you just used vmstat, sar, iostat or mpstat -a. This depends on the number of CPUs you have in your system though. Now, if you do not have a lot of CPUs, but still want greater accuracy, I have another trick. This works especially well if you are conducting an experiment and can run a command at the beginning and end of the experiment. This trick is based around the output of vmstat -s:
Those numbers are "ticks" since the system booted. A tick is usually 0.01 seconds. NEW: I have now uploaded a script that uses these statistics to track system-wide utilization. Posted by timc ( Feb 13 2008, 02:12:01 PM PST ) PermalinkComparing the UltraSPARC T2 to Other Recent SPARC ProcessorsThis is now a placeholder. You probably want to read my updated blog on SPARC processor details to get the latest. Posted by timc ( Nov 02 2007, 04:00:00 PM PDT ) PermalinkHow Event-Driven Utilization Measurement is Better than Sample-Based...and how to measure both at the same timeWith the delivery of Solaris 10, Sun made two significant changes to how system utilization is measured. One change was to how CPU utilisation is measured Solaris used to (and virtually all other POSIX-like OS'es still) measure CPU utilisation by sampling it. This happened once every "clock tick". A clock tick is a kernel administrative routine which is executed once (on one CPU) for every clock interrupt that is received, which happens once every 10 milliseconds. At this time, the state of each CPU was inspected, and a "tick" would be added to each of the "usr", "sys", "wt" or "idle" buckets for that CPU. The problem with this method is two-fold:
Solaris 10 now uses microstate accounting. Microstates are a set of finer-grained states of execution, including USR, SYS, TRP (servicing a trap), LCK (waiting on an intra-process lock), SLP (sleeping), LAT (on a CPU dispatch queue), although these all fall under one of the traditional USR, SYS and IDLE. These familiar three are still used to report system-wide CPU utilisation (e.g. in vmstat, mpstat, iostat), however you can see the full set of states each process is in via "prstat -m". The key difference in system-wide CPU utilization comes in how microstate accounting is captured - it is captured at each and every transition from one microstate to another, and it is captured in nanosecond resolution (although the granularity of this is platform-dependent). To put it another way it, it is event-driven, rather than statistical sampling. This eliminated both of the issues listed above, but it is the second issue that can cause some significant variations in observed CPU utilization. If we have a workload that does a unit of work that takes less than one clock tick, then yields the CPU to be woken up again later, it is likely to avoid being on a CPU when the sampling is done. This is called "hiding from the clock", and is not difficult to achieve (see "hide from the clock" below). Other types of workloads that do not explicitly behave like this, but do involve processes that are regularly on and off the CPU can look like they have different CPU utilization on Solaris releases prior to 10, because the timing of their work and the timing of the sampling end up causing an effect which is sort-of like watching the spokes of a wheel or propeller captured on video. Another factor involved in this is how busy the CPUs are - the closer a CPU is to either idle or fully utilized, the more accurate sampling is likely to be. What This Looks Like in the WildI was recently involved in an investigation where a customer had changed only their operating system release (to Solaris 10), and they saw an almost 100% increase (relative) in reported CPU utilization. We suspected that the change to event-based accounting may have been a factor in this. During our investigations, I developed a DTrace utility which can capture CPU utilization that is like that reported by Solaris 10, then also measure it the same way as Solaris 9 and 8, all at the same time. The DTrace utility, called util-old-new, is available here. It works by enabling probes from the "sched" provider to track when threads are put on and taken off CPUs. It is event-driven, and sums up nanoseconds the same way Solaris 10 does, but it also tracks the change in a system variable, "lbolt64" while threads are on CPU, to simulate how many "clock ticks" the thread would have accumulated. This should be a close match, because lbolt64 is updated by the clock tick routine, at pretty much the same time as when the old accounting happened. Using this utility, we were able to prove that the change in observed utilisation was pretty much in line with the way Solaris has changed how it measures utilisation. The up-side for the customer was that their understanding of how much utilisation they had left on their system was now more accurate. the down side was that they now had to re-assess whether, and by how much, this changed the amount of capacity they had left. Here is some sample output from the utility. I start the script when I already have one CPU-bound thread on a 2-CPU system, then I start up one instance of Alexander Kolbasov's "hide-from-clock", which event-based accounting sees, but sample-based accounting does not:
The Other Change in Utilization MeasurementBy the way, the other change was to "hard-wire" the Wait I/O ("%wio" or "wt" or "wait time") statistic to zero. The reasoning behind this is that CPU's do not wait for I/O (or any other asynchronous event) to complete - threads do. Trying to characterize how much a CPU is not doing anything in more than one statistic is like having two fuel gauges on your car - one for how much fuel remains for highway driving, and another for city driving.
References & Resources
P.S. This entry is intended to cover what I have spoken about in my previous two entries. I will soon delete the previous entries. Posted by timc ( Aug 31 2007, 11:03:09 AM PDT ) Permalinknicstat - Update for Solaris & LinuxI have made a minor change to nicstat on Solaris and Linux. The way it schedules its work has been improved. Use the links from my earlier entry on nicstat for the latest source and binaries. I will write up a more detailed explanation along with a treatise on the merits of different scheduling methodologies in a post in the near future. Posted by timc ( Jul 12 2007, 04:19:29 PM PDT ) PermalinkUsing DTrace to Capture Statement Execution Times in MySQLIntroductionI have recently been engaged with a customer that is evaluating MySQL, in particular with its Memory (formerly known as Heap) engine, which stores all database data and metadata in RAM.
I was asked to assist with diagnosing if/whether/where statements were taking longer than 5 milliseconds to complete. Now, this was being observed from the viewpoint of the "client" - the client was a synthetic benchmark run as a Java program. It could be run either on a separate system or on the same system as the MySQL database, and a small number of transactions would be measured as taking longer than 5ms. Now, there is more than one way to skin this cat, and it turns out that Jenny Chen has had a go at putting static probes into MySQL. For my (and the customer's) purposes however, we wanted to skip the step of re-compiling with our own probes, and just use what we can observe via use of the PID provider. How Do We Do This?Well, it is not trivial. However as it turns out, I have seen a bit of the MySQL code. I also had someone pretty senior from MySQL next to me, who helped confirm what was happening, as I used some "fishing" bits of DTrace to watch a mysqld thread call functions as we ran the "mysql" client and entered simple statements. This allowed me to narrow down on a couple of vio_*() routines, and to build some pseudo-code to describe the call flow around reception of requests from a client, processing of the statement, then return of a result to the client. It is not as simple as looking for the entry and return of a single function, because I wanted to capture the full time from when the mysqld thread returns from a read(2) indicating a request has arrived from a client through to the point where the same thread has completed a write(2) to send the response back. This is the broadest definition of "response time measure at the server". The ResultThe result of all of our measurements showed that there were no statements from the synthetic benchmark that took longer than 5 ms to complete. Here is an example of the output of my DTrace capture (a histogram of microseconds):
The ScriptFeel free to use the DTrace script for your own purposes. It should work on MySQL 5.0 and 5.1. The Upshot - Observability in the JVMThere is a nagging question remaining - why was the Java client seeing some requests run longer than 5 ms?. There are three possible answers I can think of:
Simplifying "lockstat -I" Output (or Ruby Is Better Than Perl)There, I said it. I have been a Perl scripter for nearly 20 years (since early version 3). I think Ruby has pretty much everything Perl has, and more, like:
Anyway, enough religous argument. I want to thank my colleague Neel for putting me onto it, and now I will provide a simple example. Post-Processing "lockstat -I"The Ruby script below post-processes the output of "lockstat -I". Why you ask? - well, because the output of "lockstat -I" can be tens of thousands of lines, and it does not coalesce by CPU. The script below will coalesce by CPU, and PC within a function (useful if you forgot the "-k" flag to lockstat). A very simple change will also make it coalesce by PIL, but I will leave that as an exercise for the reader. Ruby Post-Processor ScriptOne thing about this is that I would write this script almost exactly the same way if I used Perl. That is another plus of Ruby - it is easy to pick-up for a Perl programmer.
Example OutputFree beer to the first person to tell me what this is showing. It was not easy to comprehend the 90,000 line "lockstat -I" output prior to post-processing it though. You get this problem when you have 72 CPUs...
nicstat - now for Linux, tooJust a quick one to flag that I have released a version of nicstat for Linux (see below). I do not have a myriad of Linux systems to test it on, so if anyone finds any issues, please let me know. Posted by timc ( Feb 22 2007, 05:45:54 PM PST ) Permalinknicstat - the Solaris Network Monitoring Tool You Did Not Know You NeededUpdateOn the prompting of a number of colleagues, I have written a Linux version of nicstat. It is included in the links below. HistoryA few years ago, a bloke I know by the name of Brendan Gregg wrote a Solaris kstat-based utility called nicstat. Last year, I decided I needed to use this utility to capture network statistics in testing I do. Then I got a request from a colleague in PAE to do something about nicstat not being aware of "e1000g" interfaces. I have spent a bit of time adding to nicstat since then, so I thought I would make the improved version available.
Why Should I Still Be Interested?nicstat is to network interfaces as "iostat" is to disks, or "prstat" is to processes. It is designed as a much better version of "netstat -i". Its differences include:
How about an example?
References & ResourcesThe latest source and binaries are available here:
Note - the binaries will probably work on earlier releases of Solaris - as Solaris is just like that...
The Compiler Detective - What Compiler and Options Were Used to Build This Application?("cc CSI")IntroductionPerformance engineers often look at improving application performance by getting the compiler to produce more efficient binaries from the same source. This is done by changing what compiler options are used. In this modern era of Open Source Software, you can often get your hands on a number of binary distributions of an application, but if you really want to roll your sleeves up, the source is there, just waiting to be compiled with the latest compiler and optimisations. Now, it might be useful to have as a reference the compiler version and flags that were originally used on the binary distribution you tried out, or you just might be interested to know. Read on for details on the forensic tools.
What architecture was the executable compiled for?Solaris supports 64 and 32-bit programming models on SPARC and x86. You may need to know which one an application is using - it's easy enough to find out. $ file *.o xxx.o: ELF 64-bit LSB relocatable AMD64 Version 1 yyy.o: ELF 32-bit LSB relocatable 80386 Version 1 [SSE2] Note: yyy.o was built using "-native", informing the compiler that it can use the SSE2 instruction set extensions supported by the CPUs on the build system. Some more examples, including a binary built on a SunOS 4.x system: $ file gobble.* gobble.sunos4: Sun demand paged SPARC executable dynamically linked gobble.sparcv9: ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, not stripped gobble.i386: ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped gobble.amd64: ELF 64-bit LSB executable AMD64 Version 1 [SSE FXSR FPU], dynamically linked, not stripped Can I detect what version of whose compiler was used to build a binary, and on what version of Solaris?The command to use is: $ /usr/ccs/bin/mcs -p executable | object Here are some examples. The "ld:" entries should indicate what release of Solaris the executable was built on, which is a good indicator of the oldest version of Solaris it will run on.
There is a non-linear relationship between versions of the compiler ("Sun C") and the development suite ("Sun Studio", "Forte Developer", "Sun WorkShop", etc.). You can figure it out using Sun Studio Support Matrix. Can I figure out what compiler flags were used?It depends on what compiler was used, and whether you have objects.
"dwarfdump" and "dumpstabs" are available with the Sun Studio suite. Some examples:
$ dwarfdump -i gobble.sparcv9
...
DW_AT_name gobble.c
DW_AT_language DW_LANG_C99
DW_AT_comp_dir /home/tc35445/tools/c/gobble
DW_AT_SUN_command_line /usr/dist/share/sunstudio_sparc,
v11.0/SUNWspro/prod/bin/cc -xO3 -xarch=v9 -c gobble.c
DW_AT_SUN_compile_options Xa;O;R=Sun C 5.8 2005/10/13;
backend;raw;cd;
$ dumpstabs -s test
5: .stabs "Xa ; g ; V=3.1 ; R=Sun WorkShop 6 2000/04/07 C 5.1
; G=$XAB0qnBB6
6: .stabs "/net/vic/export/home/timc/tools/c/interposition;
/opt/Forte6/SUNWspro/bin/../WS6/bin/cc -g -c test.c
-W0,-xp\$XAB0qnBB6hh5S_R.",N_CMDLINE,0x0,0x0,0x0
$ dumpstabs -s getwd
1: .stabs "Xa ; V=3.1 ; R=WorkShop Compilers 4.2 30 Oct 1996 C 4.2",
N_OPT,0x0,0x0,0x0
2: .stabs "/home/staff/timc/tools/c/getwd;
/opt/SUNWspro/bin/../SC4.2/bin/cc -c getwd.c -W0,-xp",N_CMDLINE,0x0,0x0,0x0
Can I figure out where the binary will look for shared objects?If an RPATH has been specified, dumpstabs can find it:$ dumpstabs mysqladmin | grep RPATH 13: Tag = 15 (RPATH) /usr/sfw/lib/mysql:/usr/sfw/lib Can I figure out what shared objects the binary needs?Yes, just use "ldd":
$ ldd mysqladmin
libmysqlclient.so.12 => /usr/sfw/lib/libmysqlclient.so.12
libz.so.1 => /usr/lib/libz.so.1
librt.so.1 => /usr/lib/librt.so.1
libcrypt_i.so.1 => /usr/lib/libcrypt_i.so.1
libgen.so.1 => /usr/lib/libgen.so.1
libsocket.so.1 => /usr/lib/libsocket.so.1
libnsl.so.1 => /usr/lib/libnsl.so.1
libm.so.2 => /usr/lib/libm.so.2
libthread.so.1 => /usr/lib/libthread.so.1
libc.so.1 => /usr/lib/libc.so.1
libaio.so.1 => /usr/lib/libaio.so.1
libmd5.so.1 => /usr/lib/libmd5.so.1
libmp.so.2 => /usr/lib/libmp.so.2
libscf.so.1 => /usr/lib/libscf.so.1
libdoor.so.1 => /usr/lib/libdoor.so.1
libuutil.so.1 => /usr/lib/libuutil.so.1
/platform/SUNW,Sun-Fire-15000/lib/libc_psr.so.1
/platform/SUNW,Sun-Fire-15000/lib/libmd5_psr.so.1
References
How the T2000 handles 20,000 Database ConnectionsI have recently changed careers at Sun, moving from a pre/post-sales technical role to an engineer role. I now work in Sun's PAE (Performance Availability & Architecture Engineering) group. You could say I am definitely enjoying the change, getting to play with real geeky stuff :) Both jobs had the opportunity to play with new hardware, but the new job should see me get much more play time with pre-release systems, which I find very interesting. Anyway, I had the chance to do some testing on one of our new systems that many customers have also had a great chance to test on - the T2000. The workload I am using is designed to replicate a database query load that is common for some parts of modern on-line retail operations - almost exclusive relatively simple queries, running pretty much fully cached in the RAM of the database server. The queries come from a very large population of clients (5 - 20 thousand). As a highly analytical fact-oriented engineer, you need to realise that up until my first opportunity to experience the T2000 first-hand, I remained just a little sceptical that it could deliver something like the promise of what I had heard. It has been covered that the T2000 suits some workloads better than others - I was keen to get a quantitative understanding of this to support the qualitative things I had heard. My base system I had been doing tests on was an 8-CPU (16 core) E2900. I expected this would provide a pretty fair comparison to a system that has 8 cores in its single CPU. In fact I knew of some preliminary numbers for the T2000 which made be think the E2900 would come out slightly ahead. I need to update my thinking. The advantage of four threads per core is proven by reality, with the 8-core T2000 showing it certainly had greater throughput for my workload than the 16-core E2900. As you can see in the graph, the T2000's CPU consumption is well ahead of the E2900 (lower is better). Also, as I scale up the number of connections (keeping the overall throughput the same), the T2000 does not see as much of a penalty for the increase.
References:
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||