Thursday, January 31, 2008

Plotting big and small data in the same graph

(Jan 31, 2008)

Today, I helped Justin to help his friend (Jen Han?) to plot an Excel diagram with big and small data. If we use default settings, small data will just lie on the x-axis. To solve this, we need to add a secondary axis. We can do it as follows.

From a chart with default settings, try selecting a small data series. If we cannot select it, just select any thing in the chart and keep pressing arrow keys up or down to circulate highlight until we reach the small data series. Then, right click and choose 'Format Data Series...'. Next, look for an axis option and plot the small series on a secondary axis.

We will get a result like what I show below

Figure 1. An Excel plot with two y-axes (the right one is referred to as a secondary axis in Excel)

Credit: thank you ProjectWoman whom I got the information from

Wednesday, January 30, 2008

We should try to reduce initialization task ourselves

(Jan 30, 2008)

I tried implement an efficient way to build an isotropic image. For a long time, I thought a compiler optimization will handle initialization overhead automatically, but for Visual C++ 2005, it does not.

Consider the following code:

for( int z = 0; z < y =" 0;" x =" 0;"> arVoxels[8];
NVImage_t arValues[8]; // keep H.U. values of relevant voxels

In fact, we can move all declarations outside the most outer loop (z) as follows:

float fX, fY, fZ; // for true position
float fa, fb, fc; // relative voxel distance as in 2.1.
NVVoxel arVoxels[8];
NVImage_t arValues[8]; // keep H.U. values of relevant voxels

for( int z = 0; z < y =" 0;" x =" 0;" z =" 0;" y =" 0;" x =" 0;"> arVoxels[8];
NVImage_t arValues[8]; // keep H.U. values of relevant voxels

We can see that for each z, there will be two threads. Hence, if we move declarations to the most outer loop, two threads will use the same variable storage, and that is not correct. What we should do is moving these declarations just one step outer as shown below:

#pragma omp parallel
for( int z = 0; z < y =" 0;"> arVoxels[8];
NVImage_t arValues[8]; // keep H.U. values of relevant voxels

for( int x = 0; x < nNewSizeX-2; x++ ) {

From my experiment, this makes things much faster since array initialization is expensive. Note: we can even reduce initialization further if we divide the loop ourselves and create 'multiple sections'. For each section, declare its own variables. I, however, will not do this since the code will be clutter, and we have to know the number of sections before hand, which is normally equal to the number of physical cores in a system. Thus, changing CPU may cause some performance issue. Using OpenMP in this way, nonetheless, is very flexible regarding to system configurations.

Associativity in Modern CPU Cache

(Jan 30, 2008)

Recently, I have used OpenMP to perform multi-processing a lot. However, OpenMP may cause 'false share' often if we are not careful. False share is a situation that two threads write in a different memory locations, but unfortunately, the two memory locations are assigned the same cache slot. If this situation happens, performance will be degraded significantly.

Cache associativity will play an important role on this issue, especially if we have 8 cores or more.
So, let's look at cache associativity for some modern CPUs.

AMD Athlon 64 X2 has 2-way associative L1 cache and 16-way for L2 cache (ref).
AMD Phenom has 2-way associative L1 cache, 16-way for L2 and 32-way for L3 cache s (ref-page 4)

Intel Core 2 E4000 and E6000 series: 8-way associative L1 cache (ref-page 9) and from what I got from CPU-Z, it has 16-way associative L2 cache.

Intel Core 2 E8000 series: 8-way associative L1 cache and 24-way associative L2 cache (from CPU-Z).

So, I think CPUs from both manufactures should do well in scaling, but from what I got from Tom's hardware, Phenom scales very well and better than Core 2 Quad. I, however, cannot confirm this until both platform are more matured and more serious evaluation are available.

Tuesday, January 29, 2008

New line positioning problem in Visual Studio 2005

(Jan 29, 2008)

I encountered a curious problem about new line positioning in Visual Studio 2005, specifically Visual C++, from time to time. The issue is when I press enter to insert a new line. The cursor will not move down to a new line, but stick to the same line.

Today, I noticed that code folding may cause some issue about this. If the last function in a file is folded, this problem may occur.

(see Processor3.cpp)

Friday, January 25, 2008

Display ampersand in MFC controls

(Jan 25, 2008)

I tried to display an ampersand (&) in MFC controls (Visual C++ 2005), specifically tab controls. The problem is a literal "A & B" was displayed "A B" in MFC controls.

To fix this, we have to replace & with &&. Namely, use "A && B", instead of "A & B".


Wednesday, January 23, 2008

How to fix "Insufficient system resources to complete the API"

(Jan 23, 2008)

There is a blog complaining about this. It shows some reasons that this issue is a major problem for a laptop. I agree with him, although mine is a desktop.

As of Jan 23, 2008, Microsoft does not have a patch for this issue, but hotfix is available from here

Mysterious MFC Compile Error

(Jan 23, 2008)

I got a mysterious compile error today. It said one of a resource ID, IDD_SUP_VENA_CAVA is not defined / declared in this line:

// Dialog Data

Dr. Yu suggested me include resource.h. I did and it worked fine, but I really don't understand why I don't need such includes in other places. That's why I think it's mysterious.

Saturday, January 19, 2008

MFC: Practice using tab control

(Jan 19, 2008)

After try using MFC's tab control (CTabCtrl) from

The first one seems to give more concise and be easier to follow.

There are also some important points I'd like to note:
1. Do not forget to change 'style' of a tab sheet from 'popup' to 'child'. If you do not make such change, the position of a tab sheet may be at the top left corner of the screen.

2. Tab sheet should be set to have no border (Border = none).

3. CTabCtrl must be derived. It seems there is no simpler way for this, although initialization code for our derived class may be very common as used in

4. Tab control must have this message map,


Otherwise, changing tab is impossible.

5. As usual before a dialog which has a derived tab control in it can be shown, we need to 'Create' it. Declaration does not mean 'Create' at all.

m_myDialog.Create( IDD_MAIN_DLG );
m_myDialog.ShowWindow( SW_SHOW );

6. Properties for a common tab sheet are shown in the following images:

Private copy:

Monday, January 14, 2008

Blood system in the mediastinum

(Jan 14, 2008)

I found an image of major blood vessels in mediastinum. It tells me about the names of blood vessels I want to know, especially, azygos vein, right and left innominate veins.

By the way, I'd like visualization in this page

Sunday, January 13, 2008

Folder Listing in Apache

Default configuration value for folder listing in recent Apache servers seems to change. Now, by default, we cannot list folder contents without an index file. To allow folder listing without an index file, we need to set an option properly. If we start from a fresh installation of Apache 2.2, the default option is

Options FollowSymLinks

We can change it to

Options Indexes FollowSymLinks

And, directory listing will work just fine. Note: 'Deny from all' directive may still prevent us from viewing a page. We can delete or comment out the directive to view contents.

To make folder listing looks better, we should also employ fancy style by uncomment the second following line:
# Fancy directory listings
#Include conf/extra/httpd-autoindex.conf

Please consult for details.

Saturday, January 12, 2008

Web folder ของ Thai Club

If we want to access a web folder of an organization in Penn State, we need to know its path on a server. To find what it is, we can go to, log in and choose 'Add More Space (Quota Manager)'. Then, we will see a folder path in a drop-down menu. We can use the path to access our web folder.

And of Thai Club, the path is /:/services/www/clubs/wwwroot/up/thai

Tuesday, January 01, 2008


เคยได้ยินเพลงนี้มาประมาณสิบปีแ้ล้วตั้งแต่อยู่ที่ไทย พยายามค้นอยู่นานว่ามันคือเพลงอะไร แต่ก็ไม่เจอเพราะเคยถามเพื่อนแล้วเพื่อนเข้าใจผิดว่าเป็นเพลงเปลวไฟในไอหมอก แต่ท่จริงแล้วมันชื่อว่าเพลง 'สู้ต่อไป' ของศิลปินที่เรียกตัวเองว่าชาร์ค

(keywords ที่ใช้ค้นแล้วเจอคือ มองไม่เห็นทาง โลกสลัว
แต่ก่อนเราค้นด้วยคำว่า 'แม้จะมองไม่เห็นทาง' และ/หรือ 'โลกสลัวไร้แสงสว่าง' แต่ก็ค้นไม่เจอ

วันปีใหม่นี้ลองค้นอีกทีด้วยตัดคำโน้นคำนี้ออก สุดท้ายก็ค้นเจอ งงเหมือนกันว่ากูเกิลทำดัชนีการค้นหายังไงกันแน่)

ขอคัดลอกเนื้อร้องไว้สักหน่อย กลับไทยไปแล้วคิดว่าจะหามาซื้อเก็บไว้เหมือนกัน นาน ๆ ถึงจะมีเพลงที่เราคิดถึงอยู่บ่อย ๆ

ร้อง : ชาร์ค (Shark)
เนื้อเร้อง : ชาร์ค
ทำนอง : ชาร์ค & กันต์
โปรดิวเซอร์ : พลรักษ์ โอชกะ
สังกัด : ไนน์ตี้ไนน์ โปรโมชั่น


เดินก้าวไปบนทาง ที่แสนลำบาก
ใจและกายเหนื่อยจน หมดแรงอ่อนล้า
จำต้องทนฝืนทุกข์ตรม ไม่หมดลมหายใจต้องสู้

เดินต่อไปเถอะเดิน แม้ไม่เห็นทาง
อะไรกีดขวางบอกใจ ต้องข้ามให้ไหว
แม้อาจล้มลุกคลุกคลาน ไม่ว่านานแสนนานจะสู้
ก็รู้ทั้งรู้ไม่สู้ ไม่เหลืออะไร

แม้จะมองไม่เห็นทาง โลกสลัวไร้แสงสว่าง
แต่ใจบอกตัวไม่ต้องกลัว เกิดเป็นคนชีวิตต้องสู้
สู้จนยิบตา ดูให้ดี

จะมองแต่โลกในแง่ดี ชีวิตนี้แสนมีคุณค่า
ที่ผ่านมายิ่งทำให้เรา แกร่งแข็ง
สักวันชะตาต้องหมุนเวียน เปลี่ยนแปรผันทุกข์ตรมคลี่คลาย
และฝันที่เราฝันใฝ่ จะกลายเป็นจริง