Monday, July 24, 2017

ESP32 - Trials with setup in Windows 10

After hearing about the little micro-controller called the ESP32 ("successor" to the ESP8266), I was finally able to get my hands on an ESP-WROOM32.  The specs read like an IoT developer's dream - multiple ADC, I2C, I2S, DAC, LED output controller, PWM, touch input, Infrared send/receive, Bluetooth, wifi, built in temperature sensor, low power usage, among many others...and the price is relatively cheap and ranges from $10-20.

One complaint I do have for the board is its size in relation to the breadboards - inserting it into a breadboard leaves one row of pins available on one side and none on the other - pretty much have to straddle across two different breadboards to be useful.  I'm using Dupont cables as an alternate, which works well.

Getting this thing running in a Windows 10 development environment, well, that's been the fun part.  This is some of the struggles I had and what I had to eventually do to get it working.

Arduino IDE

Using the Arduino IDE, setup wasn't too bad.
I originally had an older version of the Arduino IDE installed, version 1.6.  So I upgraded that to the latest (1.8.3 at the time of this writing) and then followed the instructions on adding the ESP32 board to the Arduino board list.  This is not as simple as adding the ESP8266 but still wasn't bad.  I used a page similar to Installing the esp32 board in arduino ide windows for the instructions on how to set that up.  The WifiScan example worked well.  The standard LED blink example did not - according to what I've found, it seems the pin # for the onboard LED doesn't exist for the ESP-WROOM32.  I added a normal LED, set the pin, and it worked great.

The problem with coding with the Arduino IDE is it's a bit limited, especially when it comes to the ESP32.  There are very few libraries out for the ESP32, so that eliminates most of the advanced features of this controller.  Bluetooth, DAC, etc cannot be easily programmed within the environment.  Wifi works as well as input/output of the pins - all the stuff you can do with the ESP8266.  Most everyone online mentioned using the ESP-IDF.

ESP-IDF in Windows

Following the various online how to's on how to set up the Windows environment for using ESP-IDF, including installing MSYS32 (which is basically an embedded Linux like environment btw) did not go well at all.  Eventually gave up on it.  The use of an embedded pre-setup Linux environment was kinda a big hint that setup is not easy on Windows.

Ubuntu - HyperV

Since I'm running Windows 10 and already had HyperV setup, I tried running Ubuntu 14 in Hyper-V.  In general, setup went well but I noticed it was awfully slow.  Played around with the settings and found that RemoteFX greatly improved performance of Ubuntu...but, one big catch - I was stuck at 800x600 resolution max.  After doing some searching online, people had mentioned to edit one of the files and force a resolution - which did not work.  Another mentioned to not use RemoteFX for Ubuntu - well, that worked but now performance wise it was unusable.  So, next to try is VirtualBox.

Windows 10 HyperV and VirtualBox

Found out the hard way a year ago that HyperV and VirtualBox do not play nice together on my main PC - start up a VM on either and the host machine reboots without warning.  So, had to uninstall HyperV and then install VirtualBox.

Ubuntu - VirtualBox

Ubuntu installed extremely quickly in VirtualBox and performance was also very good so I continued to go down this route.  I set it up myself but a good walk thru on how to do this is at http://iot-bits.com/esp32/getting-started-with-esp32-esp-idf-part-1/

USB to serial port issues Ubuntu

The ESP32 worked great in Windows and was at virtual Com3.  In Ubuntu, finding which port and getting it setup to work has been a pain.  The ESP-WROOM32 has a built in USB to serial converter (if it was a true serial device I do not believe this would be as difficult).  By default, USB pass thru is turned off in VirtualBox - change USB settings with the VM off. That was the easy part.  Tell the VM to use Silicon Labs C2102 device and my KVM switches devices to a completely different computer or I lose keyboard/mouse entirely on my main machine and have to forcibly reboot (disconnecting/reconnecting does not work).

Outside of those issues, when I do finally see a USB device on the /dev/tty path (in my case, /dev/ttyUSB0), try to connect to it in Putty and I get a dreaded "Unable to open serial port" - ok, is this a "port is not working" or something else?  After doing more digging, it seems this may be a permissions issue, not a com port not working type issue.  After doing an "ls -l /dev/ttyUSB0" command, I find this is probably the issue.  Following the direction from Jesin's blog, I added myself to the dialout group and this seemed to fix the issue.  Just remember to log out or the changes do not happen.

ESP-IDF Setup and test in Ubuntu

For setup for the toolset, I used http://iot-bits.com/esp32/getting-started-with-esp32-esp-idf-part-2/ - had no issues with this setup.

For the IDF, I used part 3 of their tutorial, which also works great up to the point of their examples.  The most recent version of the IDF (v2) moves "HelloWorld" and "Blink" to a "get-started" directory - you won't see them under examples as the tutorial states.  The link to part 3 is http://iot-bits.com/esp32/getting-started-with-esp32-esp-idf-part-3/.  For my setup, I did not have to install the flash utility ("make flash" worked just fine) - just remember to not have anything else open (Arduino IDE, Putty, etc) that could already have the port open.







Monday, November 14, 2016

Exceptions and Performance

First, let me put out this disclaimer - the tests and improvements shown here are a worst case scenario done with "out of bounds" testing.  While the tests and solutions here show 4,000x+ performance improvement, this is not a typical real world scenario.  The information learned here, though, can help gain significant performance improvements in most typical applications.  Don't expect the results shown here in a normal real world application as there are normally a lot of other factors affecting performance other than just one or two pain points.

In a prior post, I discussed the issues with string equality and how to easily increase performance around those areas.  Recently I ran into another problematic problem that seems to plague code - the exception.

Exceptions, in languages such as .Net and Java, are there to let the code know when something has happened the code has not accounted for.  This could be something such as an attempt to divide by 0, a file missing, or even a network/database connection lost.  Exceptions are good things - they allow the programmer to work around the problem.  For instance, with a database connection is lost and an exception happens, the program could attempt to reconnect when it receives the exception.  Of course, there's an exception to this, there are some exceptions that can't easily be handled in user code, such as out of stack space or out of memory - most languages simply abort the program at the point of these exceptions as it's normally a sign something seriously went wrong.  But, exceptions are generally meant to be handled and accounted for, or, if at all possible, avoided entirely as they're extremely slow.

How slow?  Here's a comparison of various loops against an exception.  For the tests, the tests are executed 5 times with an inner loop that performs a simple calculation 250,000,000 times - yes, I did say 250 million.  I used 250 million as the loop count as I'm trying to get to get a baseline of approximately 1 second for the specific tests.

First, though, a walk-thru of the performance test code.

    int iterations = 5;
    int loopCount = 250000000;
    Stopwatch sw = new Stopwatch();
    int sum = 0;
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            //code to test goes here
        }
        sw.Stop();

        System.Console.Write(sw.ElapsedMilliseconds + " ");
        sw.Reset();
    }
    System.Console.WriteLine();

In general, there's nothing really special about this code.  It sets up the variables, creates a stopwatch timer (more on that in a second), and then does the loops, with the stopwatch being stopped and reset at the end.  The only interesting thing here is the stopwatch timer.

Date/time calculations, such as those done with DateTime.Now.Millisecond, are notorious for not being very accurate - they can vary and are often off by as much as 100ms (on top of DateTime.Now being fairly slow itself).  The calculations we need here need to be more accurate.  The Stopwatch timer, which is in the System.Diagnostics namespace, is normally very accurate and often to as low as 1ms.  Hence, the stopwatch timer is used here for that reason.

Now, back to the timings.

The simplest case is an empty loop that does nothing.  The results, for an empty loop, are around 754ms to do the entire loop 250 million times.  The exact times I received were:

785 742 769 748 727

Next, let's see what affect a simple calculation will have on this timing.  To help prevent the compiler from possibly optimizing the calculation away, we'll put a variable named sum (shown above) on the outside of the loop and print out the calculation of the summation of j*k, through the entire loop, at the end of the loops.  Here's the code for this simple calculation.

    sum = 0;
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            sum = sum + j * k;
        }
        sw.Stop();

        System.Console.Write(sw.ElapsedMilliseconds + " ");
        sw.Reset();
    }
    System.Console.WriteLine();

The results for this one, as we'd expect, are slightly higher than the loop with no code - average of around 938ms (so we come very close to the 1-second test I intended).  The exact results were:

959 927 911 942 953

Ok, now let's see what affect a conditional has on this - we'll check to see if j (inner loop) is 0, if so, just add k (outer loop) to sum, otherwise do the j*k calculation.  The code –

    sum = 0;
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            if (j == 0)
            {
                sum = sum + k;
            }
            else
            {
                sum = sum + j * k;
            }
        }
        sw.Stop();

        System.Console.Write(sw.ElapsedMilliseconds + " ");
        sw.Reset();
    }
    System.Console.WriteLine();

For this one, we have roughly 1324ms of time used for this summation. Almost double the empty loop and a little over 300ms than the prior example.  Still, 1.3s for 250 million calculations isn't bad.

Since we're on the topic of conditionals, can we get better speed out of the C# conditional operator (?:)?  The code technically should be roughly equivalent to the code above when it converts to IL.  So, for this code:

    sum = 0;
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            sum = sum + ((j == 0) ? k : j * k);
        }
        sw.Stop();

        System.Console.Write(sw.ElapsedMilliseconds + " ");
        sw.Reset();
    }
    System.Console.WriteLine();

The results are a bit surprising:

2308 2245 2286 2274 2317

Wait! What? Why? Why is the code above twice as slow as the "equivalent" inline code? Good question but that's one to investigate at a different time since the goal of this comparison is exceptions. The hint on this, though, is to look at the IL that's generated between the two conditional methods. [but, oh, you thought that using the newest way of doing things makes it better and more condensed? Uh, nope - can't assume anything like that - using this is almost twice as slow as the verbose code in these circumstances].

Ok, so now we have our baseline, some simple code, and two ways of doing conditions. Now, to the meat of the matter - how bad is the exception? Let's try with throwing an exception within a try/catch block. The catch block does nothing mainly for the sake of trying to get accurate timing of the performance test.

    sum=0;
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount/2000000; j++)
        {
            try
            {
                throw new Exception();
            }
            catch(Exception)
            {

            }
        }
        sw.Stop();

        System.Console.Write(sw.ElapsedMilliseconds + " ");
        sw.Reset();
    }
    System.Console.WriteLine();

The results average out to be 1382ms - oh, so just slightly above the one for the conditional then, right?  So, why am I even writing this blog to complain about something that's not a problem?  Well, look closely at the inner loop - look at the count - loopCount (250 million) DIVIDED BY 2,000,000...yes, a for loop that counts from 0 up to 250,000,000/2,000,000, which means it counts up to 125!  Yes, 125...not 100,000, just 125...so 1382ms average for just 125 exceptions!  That's roughly 10ms each exception!  Nah, exceptions aren't really a problem, they're a disaster!  The exact times I received for this run were:

1801 1269 1248 1245 1351

And, yes, 1801 seems a bit of an outlier but really it's right in line with the others at taking 14ms vs 10ms.  Either way, it's over 1 second for just 125 exceptions.

Now, I'm doing these tests in debug mode and with any CPU as the configuration.  I'm also running these tests within the IDE and with Intelitrace off (Intelitrace only makes things worse, with the worst hit coming to the exceptions test - up to a 3x further performance drop).  So, can we get better results when run in x86, x64 or in release modes?  Well, let's try:

Debug - x86
***Empty loop***
803 844 770 767 769
***Simple calculation***
901 900 899 903 905
***If conditional with simple calculation***
1248 1241 1241 1234 1234
***Conditional operator with simple calculation***
2215 2185 2196 2207 2206
***Exceptions (scaled down by 2,000,000)***
1100 1075 1070 1101 1086

Debug - x64
***Empty loop***
845 844 818 802 818
***Simple calculation***
1021 1021 1014 1023 1008
***If conditional with simple calculation***
1315 1320 1364 1371 1364
***Conditional operator with simple calculation***
2247 2204 2189 2211 2208
***Exceptions (scaled down by 2,000,000)***
2760 2922 2785 2807 2793

Release - Any CPU
***Empty loop***
136 145 138 131 132
***Simple calculation***
131 132 134 134 150
***If conditional with simple calculation***
277 266 270 271 271
***Conditional operator with simple calculation***
496 515 495 504 495
***Exceptions (scaled down by 2,000,000)***
758 793 762 816 872

Release - x86
***Empty loop***
134 142 146 134 150
***Simple calculation***
135 131 133 145 148
***If conditional with simple calculation***
267 272 258 269 260
***Conditional operator with simple calculation***
500 501 503 500 525
***Exceptions (scaled down by 2,000,000)***
794 781 816 811 763

Release - x64
***Empty loop***
240 224 208 204 203
***Simple calculation***
235 237 227 222 225
***If conditional with simple calculation***
336 332 331 334 339
***Conditional operator with simple calculation***
341 360 380 357 356
***Exceptions (scaled down by 2,000,000)***
1885 1883 1988 1973 2031

Ok, so, in general, if we're doing release mode and x86, we can get it down quite well, to roughly 6x slower than a simple calculation.  Worst case performance seems to be on the x64 with almost a 9x performance drop compared to a simple calculation.  Now, remember, the exceptions are actually only executing the loop 125 times compared to 250,000,000 for the others, so, in reality, we're talking 6x * 2,000,000 or 12 million times worse for the best case and 9x * 2,000,000 or 18 million times for the worst case. Are you having a performance issue in your application, you're debugging it in the IDE, and the app is throwing a lot of exceptions, and you're wondering why the app is so slow?  Well, to quote a famous Myth Buster - "There's your problem!"  

So, in the "real world," apps are not run in the IDE - they're started by the OS in various ways (ie command prompt, service/daemon, etc).  What affect does the IDE have on exceptions?  Well, let's see...same tests, same code:

Debug - x86
***Empty loop***
752 748 746 759 758
***Simple calculation***
887 890 895 890 883
***If conditional with simple calculation***
1213 1209 1202 1205 1186
***Conditional operator with simple calculation***
2162 2241 2164 2155 2162
***Exceptions (scaled down by 2,000,000)***
2 2 2 2 2

2ms for exceptions now?  The entire loop ran in 2ms?  The fun part here is 2ms for just 125 executions of the loop.  Let's drop the scale down a bit and see how it does.  For the following runs, I've set the scale to be 4,000, so the exceptions loop runs basically 62,500 times and we get the following results for each of the various build configurations.  Remember this is outside the IDE (or also via Ctrl-F5 within the IDE).

Debug - x86
***Empty loop***
768 758 771 764 752
***Simple calculation***
888 901 891 889 890
***If conditional with simple calculation***
1216 1219 1254 1233 1227
***Conditional operator with simple calculation***
2162 2173 2157 2157 2170
***Exceptions (scaled down by 4,000)***
1287 1311 1352 1292 1479

Debug - x64
***Empty loop***
820 803 834 793 791
***Simple calculation***
1010 1018 1026 1014 1042
***If conditional with simple calculation***
1413 1290 1295 1315 1293
***Conditional operator with simple calculation***
2237 2235 2270 2314 2277
***Exceptions (scaled down by 4,000)***
948 949 1011 996 990

Release - x86
***Empty loop***
139 133 135 131 134
***Simple calculation***
131 131 130 135 132
***If conditional with simple calculation***
261 260 263 266 263
***Conditional operator with simple calculation***
504 519 503 514 513
***Exceptions (scaled down by 4,000)***
1407 1392 1446 1407 1358

Release - x64
***Empty loop***
133 141 134 133 152
***Simple calculation***
600 602 596 599 604
***If conditional with simple calculation***
597 603 607 612 592
***Conditional operator with simple calculation***
599 599 591 599 587
***Exceptions (scaled down by 4,000)***
885 901 883 855 931

So, about 500x faster outside the IDE (125x500=62,500).  Still, though, at best case we're talking roughly 4,000x slower than the simple calculation itself...  Still, a large enough difference to be a fairly major problem when exceptions are being thrown a lot.

Am I saying we should abandon exceptions?  No, not at all (sure, abandon them and go back to what - the "on error gosub" of the VB era?).  I am saying that we should use them for what they're there for - they were designed to give details about a problem that the code did not account for.  They should not be used for control flow to break out of methods nor should they be "allowed" to happen "on their own" without code trying to find and avoid the problem first.  The simple answer is exceptions are expensive - guard against them to keep them from happening in the first place, where it is possible and where it makes sense.  If the code expects a file to exist, verify the file exists before you try to do something with it - don't assume that because you checked for the file 30 seconds prior that it still exists.  Do the checks and guards where it makes sense in the code.  If exceptions are extremely rare and should "never" happen, the guard does still cost so use judgment there, but, for things that are possible to happen, definitely try to guard against them to prevent the cost of the exception hit.

Just as an example, let's try a similar test to above but with a guaranteed failure for a certain percentage of the test.  We'll do a 0-100% fail rate (for space, the results for only 0-10% will be shown) over a smaller loop count of 2,500,000.  The code to do the test and avoid the division by zero exception looks like:

int sum = 0;
System.Console.WriteLine("***J/K summation***");
for (int l = 0; l < 101; l+=1)
{
    double remainderValue = loopCount * (1.0 - l / 100.0);
    double avg = 0.0;
    sum = 0;
    
    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            if (remainderValue < 0 && (int)remainderValue >j)
            {
                sum = sum + k * j / Math.Max(0, 
                   (int)remainderValue - j);
            }
            else
            {
                sum = sum + k;
            }
        }
        sw.Stop();

        avg = avg + sw.ElapsedMilliseconds;
        sw.Reset();
    }
    System.Console.Write("  " + (int)(avg / iterations) +
        " (" + l + "%) ");
}
System.Console.WriteLine();

And the code that allows the exceptions to happen looks like:

System.Console.WriteLine("***J/K summation w/ exceptions***");
for (int l = 0; l < 101; l += 1)
{
    double remainderValue = loopCount * (1.0 - l / 100.0);
    double avg = 0.0;
    sum = 0;

    for (int k = 0; k < iterations; k++)
    {
        sw.Start();
        for (int j = 0; j < loopCount; j++)
        {
            try
            {
                sum = sum + k * j / Math.Max(0, 
                    (int)remainderValue - j);
            }
            catch (DivideByZeroException)
            {
                sum = sum + k;
            }
        }
        sw.Stop();

        avg = avg + sw.ElapsedMilliseconds;
        sw.Reset();

    }
    System.Console.Write("  " + (int)(avg / iterations) + 
        " (" + l + "%) ");
}
System.Console.WriteLine();

The results, not performed in the IDE, for the first 10% without exceptions looks like:

***J/K summation***
  26 (0%)   27 (1%)   25 (2%)   23 (3%)   25 (4%)   24 (5%)
  25 (6%)   23 (7%)   32 (8%)   29 (9%)   32 (10%)

And with exceptions, also, not in the IDE, the timing looks like:

***J/K summation w/ exceptions***
    28 (0%)  617 (1%) 1227 (2%) 1826 (3%) 2292 (4%)  2708 (5%)
  3260 (6%) 3787 (7%) 4154 (8%) 5126 (9%) 5412 (10%)

So, at even 1% of the data failing (25,000 items out of 2,500,000), we're seeing roughly a 30x drop in performance and at 10% fail rate (250,000 items) we're seeing over 150x drop in performance - and this drop is already above the "slower performing" code that has the guard clauses in it to prevent the exceptions.

Hopefully, this makes the point fairly clear - exceptions are expensive, even when compared to adding in guard clauses to help prevent them.  Even a small frequency of exceptions can cause substantial performance problems in an application so prevent them when you can.  

Sunday, July 28, 2013

Storage Pools, Dynamic disks, and software RAID experiences

A quick disclaimer - I am no where near an expert on Windows Server nor on server equipment.  As I have with programming, I'm learning and struggling on my own - best way to learn in my opinion.  With that, I know I am not using recommended equipment nor recommended practices so some of this may be my own fault, but, if I'm out there trying to do this, there will be others as well - hopefully this'll help someone out there or help prevent others from wasting as much time as I have on this...  But, as with anything else, your experiences may vary and I am not responsible for any data loss - this is what worked for me and may help or it may not.

As with many of us in the digital age, I have a TON of data that I want to keep and ensure it doesn't get corrupted or lost thru equipment failure.  In my case, this was over 1TB of WinRar files of personal file backups (from files dating back to 1993), 500GB of pics and videos, among some Tivo files, etc.  On top of being a digital pack rat, I also hang onto computer equipment and gather equipment as I come across it.  So, two of my prior computers were not being used and I had a ton of spare [i.e. not being used] SATA hard drives so I decided to build two file servers from these pieces.

The first system was based on an Intel 975XBX motherboard.  Since I planned on loading this thing with SATA drives, I decided to get a cheap server case and my first choice was the Rosewill RSV-L4500 (http://www.newegg.com/Product/Product.aspx?Item=N82E16811147164).  This case is a beast with 15 internal drive bays.  The case worked ok except when the drives failed or when I wanted to upgrade drives - having to open it up, find the failed drive (harder than it sounds with no indicator lights on which drive failed), and replace it along with moving the internal fan bar - anyway, it was a pain to replace drives in this case.  Good case, keeps the drives cool, but would be easier with hot swap drive bays.  In addition to the motherboard, I added 2 4-port SATA controllers but did not necessarily go after those controllers being RAID - I wanted cheap, with good ratings, with 4 SATA II+ ports.  One of the controllers, a Koutech IO-PSA420 (http://www.newegg.com/Product/Product.aspx?Item=N82E16816104006) did include RAID support.  One of the motherboard's controllers also supported RAID as well.

The second system was based on an Intel 975XBX2 motherboard (very similar to the prior one).  Since I learned the lesson on needing hot swap bays, I went after a similar Rosewill case, the RSV-L4411 (http://www.newegg.com/Product/Product.aspx?Item=N82E16811147165).  Again, had to get two additional 4-port SATA controllers - same story as before, none were specifically RAID - this time I went after SATA III controllers.  I bought two of the Syba SI-PEX40064 controllers (http://www.newegg.com/Product/Product.aspx?Item=N82E16816124064).  At least one of the controllers on the motherboard included RAID support.

Now, for the drives - the drives ranged from 60GB drives to 1TB sizes, a few being enterprise level drives, some being notebook drives (1TB ones taken out of new systems in favor of 120GB SSDs - yes, they're that much worth it!).  Wide mix of brands and sizes.  I had more than enough drives to completely fill both servers - 27 drives total with a total of about 5TB of storage space - all individual drives.

Initially these systems had Windows Server 2012 Essentials loaded on them.  While nice and worked (kinda - domain issues with Essentials), I was not fond of the split usage of the drives - a backup share, for instance, was across several drives because the drives didn't have enough concurrent space to hold the entire folder.  I looked at resolutions to this - my first discovery was data deduplication, which is a new feature in Windows Server 2012, but, of course, was not available to Essentials.  Data deduplication claimed space savings as high as 75% or higher...so in theory a 1TB drive now becomes a 1.75TB drive?  I figured it was worth the upgrade risk...

So, after the upgrade, I noticed the feature of storage spaces, which is also new to Windows Server 2012 (and available in Windows 8).  I read up on it and essentially it is a software RAID, but with a bit more control.  I took all my individual drives, added them to a mirrored pool, and copied data to the pool.  While I had a nice big drive, and it seemed to be fairly safe, my transfer rates were horrible - I'm used to 30-60MB/sec transfer rates and I was getting 10mb or less per second, with often minutes at 0mb/sec.
After the failed storage spaces attempt, I tried data deduplication, which, in theory, would help on my space issues.  I turned it on for several of my larger drives, ran a power shell command to force it to deduplicate the data and I later found I had 300GB extra on that 500GB drive - nice.  I tried moving files and a similar problem happened with storage spaces - remove a 50GB file and I get back 50K of space?  Yes, data deduplication worked but with that type of recovery after a delete, I needed to combine drives as I was still having the issue of the split share across drives.

So, now, RAID...something I've tried before but never had good success with but figured worth a shot again.  Since I had few hardware RAID controllers, I figured I'd try software RAID - via Disk Management in Computer Management.  Software RAID in Windows is done via dynamic disks - the disks can be spanned (JBOD), striped, mirrored, or RAID 5...there is no option for RAID 6, 10, etc.

On the hot swap server, I set up 2 1TB mirrors (on a pair of WD Green 1TB drives, and a pair of Samsung 1TB laptop drives).  I moved all my data from my individual drives onto one of the two mirrors (one for the file backups, the other for the pics, etc).  The performance was poor, again with lower than expected transfer rates (this is a mirror so I was expecting some slower).  I read that RAID-5 and RAID 10 was a better solution for better performance so I decided to go that route.

After over a day of copying, I set up a software RAID 5 array with 3 500GB hard drives.  My thoughts were to put the data there and then switch the 2 software mirrored 1TB's to RAID 10.

Performance of the RAID 5 was better than the mirror but still pretty sluggish at times (i.e. KB/sec) - but at other times I was able to get 150MB/sec, which is pretty good compared to what I had been seeing.  I did not enable data deduplication on these drives as there was a clear warning to not do that on a dynamic volume - if the dedupe database got corrupted, it was possible to lose all data!

Once all the data was copied onto the RAID 5 array, I rebooted and set up the hardware RAID 10 array using the 4 1TB hard drives.

Upon starting up Windows again, the RAID 10 array showed up as a 2TB drive - as expected.  I figured I'd get the data off the RAID 5 onto that single logical drive, but, one major problem - the RAID 5 showed as "failed."  The good thing about RAID 5, in theory, is if one drive goes off the array or goes bad, the array can rebuild itself and recover.  So, figured I'd reactivate or try to rebuild the array but everything I tried that was suggested on Google and Microsoft, failed.  I was not able to get access to the data on the drive or even get the drives to rebuild.  I tried switching the drives to a different controller (software RAID and Windows keeps track of the drives that are in the array) but still no luck.  I even tried a few suggested software packages that were rated high for recovering data from corrupted RAID 5 volumes and after a week and a half of scanning from products such as Zero Assumption Recovery and ReclaiMe Free RAID Recovery, the most I was able to get valid was 4 50k files and 450MB of very corrupted RAR files.  No luck.

Figured I'd pull the RAID 5 drives out, back them up at the sector level, and put them into the other Windows Server to see if I could import the array and get the data that way.  During this, I also checked the drives and all were perfectly fine sector wise.  But, one of my favorite products for partition/backup of drives, Paragon Hard Disk Manager 12, decided that it would not do a sector backup of any of the drives - never gave a good enough error message to determine why.  At this point, I figured I'd already lost the 1TB of data so I was willing to try anything.

I put the failed drives into my other Windows Server and imported the foreign disks.  It showed the correct number of drives for the array (3), as expected.  I clicked ok and it came up with the size I was expecting as well - about 1TB, but the condition was "data incomplete."  Figured, ok, this may work - except the next error message gave me cause for concern - "some of the volumes you are importing will lose data because you have not moved all your disks to this system.  Are you sure you want to continue?"  Um - WHAT? I imported all the drives! Can't do a sector by sector backup and now Windows tells me this.  Did some research online and they said this error message was a bug and that it was "safe" to continue.  Figured I'd go with the general crowd sourced info and go for it - clicked ok and now I was right back to where I started with the prior server - the entire RAID 5 showing as "failed."  Like on the prior server, tried reactivating the disks (all of which showed as online).  Kept getting the "the attempted operation cannot be completed.  The selected volume is offline."  I eventually found some documentation on the Window's diskpart command (a dos version of computer management, which has a bit more capabilities than computer management).  The information it showed showed that everything should have been good and that the drive was ready...but, I still could not repair it (it didn't show it as failed), etc.

Then I came across a similar utility to diskpart that had directory and copy capabilities and was written in C# - all were pluses as I just wanted the data off the drive.  The tool is called RAID5Manager and was written by Tal Aloni - (http://iknowu.dnsalias.com/files/public/RAID5Manager/Raid5Manager.htm).  I tried the utility and was able to access the array without any issues...and doing a "dir" command, I was able to see directories!  Changing to the various directories, I was able to also see the files I expected to see.  I figured this was too good to be true so I copied a small file to another drive, opened it up and it worked!  Tried a larger RAR file, since RAR has built in consistency checks, and to my surprise WinRar opened the file without complaint!  Fun part was the utility only does single copies of files - no wildcards, etc, but, since the utility was written in C#, it wasn't hard for me to add that myself.  After about 5 minutes of code changes, I redeployed the updated utility to the server and did a copy and all files went to the backup drive without any issues.  I checked many files and all were in tact!  This utility saved me from losing 1TB of backup data to a failed data redundancy RAID 5, that, according to diskpart, was not really failed.  Not sure why/how this array got in this state (nor how to get it out except blow it away) but this tool helped recover all the data.

So, lesson learned, while I got "lucky" this time and was able to get my data back, ALWAYS backup data in multiple places - even things such as RAID that should recover data in case of failure will fail - the question is just "when."  In my case, I believe a Windows Server bug bit me hard on this failed RAID 5 volume but no proof either way.

To sum up my experiences:
1.  Storage pools - not a good idea, especially if you'll be moving files or need performance (i.e. media server).
2.  Dynamic disks - good concept but RAID-5 seems buggy.  Performance was ok but not consistent.
3.  Data deduplication - good concept/theory, but do not use on a RAID/dynamic volume!  Great returns for data that is rarely used (i.e. backups, archives, etc) but not great for those who move files often (a 50GB file deleted does not mean you get 50GB back - could be very little recovery).

All the suggestions out there always say use hardware RAID, if you need data redundancy, and use RAID compliant drives - which means more money.

Anyway, hope this helps someone out there, especially getting data off a failed dynamic RAID 5 volume that has failed.

Thursday, August 30, 2012

New PC Build

Been a while since I blogged or built a system. Figured I’d try to get back into it again by posting another build entry – this time for my own PC.
This will be my first “from scratch” build for myself in 7 years (AMD 939 system was that one), and about 4 years since I bought a couple used mostly-built systems (both Intel Core 2 Duos). Here’s what I decided on to replace all 3 systems and my thoughts during the build. 

First off, the case:
I wanted a case that had tons of drive bays, was easy to install 2.5” SSD’s and included USB 3. There were several cases that fit these requirements but the Rosewell Blackhawk-Ultra really caught my attention. The biggest thing that grabbed my attention was that 8 fans were already included – and the system had capabilities of a total of 15 fans! I knew my new machine was going to run warm so included fans are a big plus as are optional additional fans. Also liked the fact that this case supports motherboards from ATX all the way to HPTX – nice feature especially if I wanted to do a dual or quad CPU system in the future. Also liked the fact that the power supplies can be mounted on top or on bottom – or both (must remove one of the top fans to install on top though). Overall, great case – HUGE and heavy. TONS of room. The case is also very well built.

Case (Rosewell Blackhawk-Ultra)

Clearance after casters added



Bottom of case

Casters on carpet - just enough clearance to move

View of Top Control Cables

View of Back side of case


External Drive "Quick Connect"
This thing is huge - just a bit over 2 ft tall and heavy even empty

  1. Huge case but not as big as I had originally thought. For some reason I was thinking super tower would be a mid-tower (Antec P-180 size) plus the next size down from that in a single case – or, in other words a bit over 3ft. But, this is still pretty big, P-180 + the size of the quad drive cage of the P-180…or, a little less than 25” tall after casters installed. This case is also much deeper than the Antec case…so it does not easily fit on my desk without hanging off. This case also sports a huge 230mm fan - massive compared to the 120's I'm used to. Very quiet fan, nothing like I thought it would be. Low RPM speed as well.
  2. Two Extended 12v power cables included. Would’ve been nice to include ATX motherboard power extension + a full range of extended length SATA/floppy/IDE (ok, scratch that on IDE :)) cables. An added plus would’ve been to include a molex to single multi drive (i.e. 4+ drive) - SATA cable (i.e. like this one - http://www.newegg.com/Product/Product.aspx?Item=N82E16812400127) .  This is a pipe dream but would’ve been nice. Doubtful anyone does that, even on a $3k server case.
  3. Fan "hub" - uses one molex to power multiple fans. There are two of these inside the case. Nice but no control over fan speed, etc. Added feature would be to take the fan PWM signal from the MB and amplify it using one of these hubs. Or, at least a fan controller per hub.
  4. Side panel can use 230 or 9 120mm fans. Yes, 9 120mm fans on side panel! Power would be a pain. A hub for that would be nice – that is not included!
  5. 230mm fan very quiet but not a ton of airflow.
  6. Casters included. Can be used without casters and still very stable.
  7. 3 positions available for each caster. Nice to not be restricted to a specific position.
  8. With casters, case is still stable. Does not add excessive height to the case.
  9. Just enough clearance to clear the carpet without dragging (~.5")
  10. A plastic parts case for screws would be nice (like the Antec P180 series). Instead these are in a plastic bag, all mixed.
  11. Separated screws would be nice - hard to find some – this is just a minor gripe. So many screws look so similar! All are pained black which is a plus as they match the case very well.
  12. Manual included but minimal – sufficient though.
  13. Top or bottom (or both) mounted power supply. If top mount, one of the top fans has to be removed.
  14. All 10 internal drive bays as 3.5 or 2.5 capable. Would be nice to include standoffs, even if just paper ones, for 2.5” drives. Would be very nice to have “hot swap” drive cages.
  15. Red LEDs on the visible external fans aren’t too bad- would be nice to be able to turn them off. The blue power LED is pretty bright though.
  16. Lots of pass-thru areas for hiding cables. Lots of room for small to extremely large motherboards. I think a quad CPU board could easily fit.
  17. Top-mounted controls and cables are more than ample length to reach motherboard. No firewire port on case though. Not a huge deal but worth noting.
  18. Cables are arranged on the back-plate so no hanging cables by "default." These cables go to the top-mounted SATA drive mount, and the front-panel controls.
  19. Fan power cables for the front drives were not protected and are easily caught in the back panel's channels – they really need protection or at least attachments or even channels to keep them in place without them getting caught
  20. Stand off tool - used to take off standoffs instead of using a wrench/pliers – very nice addition. Manual said 2 were included, only got 1. Still, one is enough. Thought it would be easy to hand loosen the existing standoffs, but had to use a screw driver to get them loose. Configuration was not for a standard ATX board but the next larger size. Easy change and they are labeled but I still put the board in the case and verified positions.
  21. Plenty of screws. Way too many at times due to them not being pre-separated.
  22. Suggestion from manual is to bottom-mount the PS with fan down. Warning is to keep the bottom dust-filter clean or the PS may burn out early. Agree with what others said on Newegg/Amazon. If we should keep dust out of that area, make the filter washable and accessible from the front. Decided to still go ahead and point PS fan down.
  23. Velcro strap - ??? Can't be to hold PS in place (not long enough). Had to undo caster to get it unstrapped. Still unsure of its function.
  24. Bottom of case and where the power supply attaches to the case have rubber pads to keep PS vibration down - nice addition.
  25. Top mounted SATA drive port – looks like only designed for 2.5” drives – opening not large enough for 3.5” drives. Manual does not state either if this is a SATA II or SATA III compatible port.
Next, the power supply:
I wanted a power supply that was modular (to keep air flow going), decent efficiency rating, and powerful enough to run an 8-core AMD system. Did the NewEgg power supply calculator and it stated I needed a minimum of 300w power supply. I know from experience that 300w won’t get you much in terms of tons of extra hard drives – so I doubled that just to be safe. Should have plenty of additional power if needed. Currently with the configuration shown here, it uses ~150w “normal/idle” use.

Power Supply (Coolmax ZU-600B )

140mm Fan w/ view of non-modular plugs

Modular plugs included

View of modular cable ports

Installed in case

  1. 600w - more than enough for what I plan to run initially. Extra traditional SATA drives may push it over its limit but at ~20w (or less) each, should be plenty even for a full case of drives.
  2. This is a partial modular power supply - has cables for almost every system now (motherboard power + 4, 2 molex, 2 SATA, 1 8-pin PCI-Express power). Modular cables are for 3 extra SATA, 1 6-pin PCI-express (video card), 1 6 or 8-pin PCI-express (video card), and last modular is for 1 floppy and 3 additional molex. Found out the molex connectors aren’t exactly “standard” and wouldn’t work with the side fan’s connector. Molex worked in all other areas though.
  3. Manual is online - not a big deal, just interesting.
  4. No screws included - not big deal. Case came with plenty. But, that’s one thing I’ve come to expect over the years, even with “cheap” power supplies.
  5. Power supplies and their cables are not designed for cases of this size. Just due to cable length, had to use the molex modular cable just for the fans since one fan panel is at top, one is near bottom.
  6. Routing the power cables takes some thought with this case.

Have a case and power, now need storage space:
Being stuck at SATA II drives (and on the AMD, IDE drives), I wanted to try out all the new technology – from SSD to traditional SATA III. Went with a Blu-ray burner as well.
Drives
All 3 drives installed

Drive tray with 3.5 and 2.5 options

Mounted the drives in reverse of what I would normally think - power and SATA cables towards the back side of the case. A PAIN if you upgrade or add/change drives often to have to remove BOTH front and back panels. Oh well. Really would be nice to have a RAID-like or hot-swap bays. I did not check to see if the drive cages could be installed “backwards” so that you’d only have to take off the back panel when adding/upgrading a drive.
Decided to put a bit of space between the standard drive and the SSDs - heat has always been an issue with normal drives...even with the fans, I'm a bit cautious.

SSD (SAMSUNG 830 Series 2.5-Inch 128GB SATA III MLC Internal Solid State Drive (SSD) MZ-7PC128B/WW )




  1. Wow, this thing is tiny - at first thought it was sample blank Blue-Ray discs. Totally sealed so no exposed circuitry. Surprised by the 1.5A power requirement (~8w) though - seems high.
  2. Felt like I was going to break the power connector on both 2.5” drives – seems a bit flimsy compared to the 3.5” ones.
  3. Boy is this drive fast! Never seen anything this fast! I was able to install Windows 7 Ultimate from DVD to this drive fully in ~13 minutes – with ~2 minutes of that being from the install wizard itself and human speed. Like a former co-worker told me, I will not want to go back to traditional drives after being on this drive!

Blue-ray (LG Electronics 14x Internal BDXL Blu-Ray Rewriter with Software WH14NS40 )

Drive itself

Exterior faceplate removed - after much coaxing
 
Empty drive bay - no steel plate, thankfully

Installed drive

  1. Surprising - no manual, no sample disks – it is an OEM so not really expecting it. SATA cable and Molex to SATA power adapter though and software CD/DVD were included.
  2. One of the things I always hate about installing external drives is the plate that normally shields that area. Rosewell was nice for the topmost drive and didn't install the steel plate - but the nice "shield" that covers the hole was a PAIN to get out. I did not remove the front panel of the case (come on, installing one drive here, not redoing everything front facing). Had to take a flat head and pliers to get it out after a bit of hammering on it with the flathead. Not easy - had much easier. Like another reviewer said, that ain't going back on there.
  3. The "quick install" drive feature on the one side of the case is nice – very easy to do...other side, if you want the drive "stable" requires screws. The quick install feature is nice, but, um, I'd rather have this on the drives I'll change often such as the 3.5/2.5" ones - am not going to fight the case to do another external drive. Nice feature but not worth the money IMO.

Hybrid (Seagate Momentus XT 500 GB 2.5 Inch Solid State Hybrid Drive ST95005620AS )

Hybrid drive with paper spacers
  1. Tiny little thing - about what I'd expect for a laptop drive (1.8/2.5"). Very nervous about putting this in the drive cage as is as there's very little separation between the exposed underside of the circuit board and the metal cage. Drive really needs a spacer of some sort. But, I guess it's meant as a laptop drive, not to be put in a desktop case. Found some old paper spacers from the age of the 486's - put those between the cage and the drive to add a micron more space. Rather not see a drive or power supply go up in smoke. Drive seems to be fine and works without issue. Have not tested speed yet but the hybrid is meant to store commonly used files in SSD and the rest on magnetic. With the SSD being master, not going to be easy to test raw performance of that.

SATA III (Western Digital 1 TB WD Blue SATA III 7200 RPM 64 MB Cache Bulk/OEM Desktop Hard Drive )


  1. Now this is what I'm used to. SATA III 1TB WD Blue. Nothing at all new here other than SATA III. Drive installed fine.

Cooling:
Since I’m running an AMD processor and since it’s also 8-core and meant for overclocking, I decided to go water-cooled – also, a first for me. After reading many reviews, decided on the Thermaltake Water2.0 Pro. So far it’s keeping the stock-parameter AMD 8-core, when idle, at 32C – have seen it go as high as 48C under load. Not bad, especially when my Intel Core 2 Duo systems were sitting around 55C+. Prefer to keep temps below 40C – running a computer, not a stove :)

Water cooler (Thermaltake Water 2.0 PRO/All In One Liquid Cooling System CLW0216 )


Water cooler radiator and 2 fans

Parts for Intel or AMD

Pump itself (with installed brackets for AMD) showing thermal paste

Back of Motherboard with installed cooler plate
 
Water cooler installed

Another view of water cooler

Another view - notice the room in this case vs the motherboard

  1. About what I expect for a after-market/non-stock air cooler. Misc parts for Intel/AMD, fans, radiator (i.e. heatsink), etc. So far so good...and one plus, no leaks in the box [blaming UPS, not mfg's/NewEgg] :) A plus - a manual :)
  2. No thermal paste included though it appears to be some on the pump itself. Time to read the manual to make sure. And, yep, first page of the manual suggests "read this manual thoroughly and follow all steps in order"...hmm. Ok, first off it's install pump – but this is hard to do without a motherboard installed...
  3. I do feel like I'm working on a car with this radiator though. Not huge, but still.
  4. Instructions are not completely clear for first time water-cooler installers - backplate for CPU, does that come off or no? I voted for yes – and it is required to take that off first. Manual said read carefully and follow directions in order and that was one of a few steps they left out.
  5. After getting the cooler installed (pain, btw) [but probably normal for users who're used to doing after-market air coolers - I'm not, been 4 yrs!]. And, yes, the thermal paste is on the pump - pretty clearly stated don't touch it in the manual. I did not add additional thermal paste.
  6. Cooler is QUIET and so are the fans. Would like a bit more control over the cooler. Believe the next step from ThermalTake has that feature.


Now for the motherboard, CPU, RAM, and video card, then back to the cooler:
I really like all of Asus’ products – from their Netbooks to their tablets to their motherboards. Haven’t had a single problems with any Asus equipment I own or have built for others. Great company in terms of quality!
For the motherboard, one requirement I had was Firewire. Asus has 3 990-based boards (the 990 chipset was also one of my requirements). One of my requirements was a Firewire port – of which the Sabertooth has and so foes the M5A99X EVO. I liked the 3 PCI-express slots on the Sabertooth
Motherboard (Asus Sabertooth 990FX) and also the thermal radar, military spec components, etc. Extra USB 2 ports was also a nice feature.

Motherboard (ASUS Sabertooth 990FX TUF Series Motherboard AM3+ DDR3 1800 - 990FX )






Quick-connect headers

5 year warranty and cert of reliability


Various components included

Wow, tons of room in this case!

Installed motherboard

  1. Motherboard install was pretty standard.
  2. Motherboard set inside the case really shows how HUGE this case is.
  3. Was surprised that only one side of the memory release levers went down – the other is fixed and doesn’t move. New feature to me.

CPU (AMD FX-8150 FX 8-Core Black Edition Processor Socket AM3+ - FD8150FRGUBOX )





  1. Nice TIN box, not the cardboard ones I'm used to. Easy install - nothing new here.

Memory (G.SKILL Ripjaws X Series 32GB (4 x 8GB) 240-Pin SDRAM DDR3 1600 (PC3 12800) Desktop Memory F3-12800CL10Q-32GBXL )

  1. Well, these were a pain - the plastic case was difficult to get the chips out. Got them out but prefer an "easier" container. Same old same old here.

Video card (GIGABYTE GV-R667D3-1GI Radeon HD 6670 1GB DDR3 DVI-D / D-Sub / HDMI CrossFire Ready Graphics Card )

Nice fan/heatsink on video card

  1. Video card has a fairly nice heatsink and fan. The fan is pretty quiet.
  2. Did not see a Crossfire port. From what I’ve read elsewhere, it uses “hyper-crossfire.”
  3. One HDMI, one SVGA, one DVI port.
  4. Performance is decent.
  5. Actually have a 2nd video card coming – nice to have quad monitors and also experience crossfire (while it existed on prior builds, I never used it – didn’t see the sense as I don’t do a ton of high-performance gaming).


Final comments on case, water cooler, and power supply:
Case and PS
  1. Additional comment on the 230mm fan and PS - the molex connector on the PS did not fit the molex for the fan - bit of a annoyance. Had plenty of motherboard connectors...but, the side panel fan is now relatively closely tied to the case. Oh well...
  2. Did think I was going to have a problem with the 230mm fan and the water cooler - seems to be a good fit after all. At first thought the water cooler was in the way of the fan, but that is not so.

Water Cooler
  1. Water cooler radiator as installed is opposite of what the book recommends - the tubes were just too close to comfort for me to the power regulators (which have heatsinks, which means they will get warm/hot) and the bends were a little too tight. Fits fine with the tubes towards the outside of the case.
  2. Also, did not use the included Y connector - motherboard has plenty of fan connectors. One thing did concern me on the Y - one connector looked like it was missing a pin (and wire), the other had all 4 - book did not say which fan/pump should go where. Both fans and pump are on motherboard fan connectors. Cools pretty well as is so leaving alone for now.

Conclusion
About 4 hrs total to put together but was taking my time and documenting as I went. Everything worked first try. Win 7 installed in 13 minutes from a DVD. SSD card is handling Win 7, Visual Studio 2010 Ultimate and 2012 Ultimate, Office 2013, and SQL Server 2012. Still has plenty of room left.  System goes from login screen to ready to use in ~2 seconds.
So far, it's extremely difficuly to get the SSD drive to get to100% usage - I can usually easily do this with a traditional drive.  Drive rarely gets above 10% usage.
CPU also stays pretty low - usually around 20% total.
Motherboard's BIOS is nice - allows for easy overclocking.  I haven't done so yet.  The BIOS has a setting that allows the system to be overclocked into turbo mode, which is 4.2Ghz instead of the 3.6Ghz.  Can't tell the difference either way.

Windows 7 Experience Index with stock settings:
Processor - 7.7
Memory - 7.7
Graphics - 6.8 (overclocked slightly for a 6.9)
Gaming Graphics - 6.8 (overclocked slightly for a 6.9)
Hard Drive - 7.9

UPDATES
Ordered a second ATI 6670 card with the goal to crossfire the cards and to get a quad-monitor system going.  While in the case to add the card, I noticed the power supply itself was fairly warm so I removed the dust filter from the bottom of the case (it is relatively easy to remove - but would be a pain to do more than just a couple times).  That should help open up the bottom of the case and allow more air into the power supply.  I'd thought about flipping the power supply but the motherboard power cables are already pretty tight - will try it this way first for a while.

Also moved some of the fans to be motherboard-driven instead of off the fan hub.  Should allow me to keep better control of the areas that don't have fans on them (such as the vcore's).  They and the PCI-Express cards seem to run a bit hotter than I'd prefer.  So far the moving of the fans to the motherboard along with adjusting the fan speeds seems to have dropped those temps down by 6C. 

Unlike what I understood, the ATI 6670 card can not be crossfired as normal cards can (via the bridge) - there is no bridge connector on the cards!  From what I've read elsewhere, they're "hyper" crossfired via the PCI-Express bus.  The ATI software did allow me to enable crossfire but doing Windows experience testing did not show any improvement so not sure if it didn't work at all or just not seeing any gain.  Even with 2 cards in the system (with crossfire on or off), the video performance stayed at 6.9.  Have seen other reports that say the ATI 6670 cards aren't worth crossfiring as a single 6870 series card is faster than the dual ATI 6670's would've been and is actually cheaper total cost.  Not in it for the graphics/gaming so not too concerned about it for now.  Little disappointed but, oh well, crossfire is a feature I won't use much anyway.  But, good news is that an additional video card only rose the wattage requirements of the system by 25W idle (from ~125W to ~150W) [as per the reading from my UPS].  With all 4 monitors running, total power draw sits around 300W total - course the monitors are adding 150w from the mains, not from the power supply.  Really nice to have a quad monitor system and a system that has lower power draw than my prior system.

And the Asus motherboard, well, it seems Asus has relased version 2 of that motherboard with new features.  Some neat features (i.e. single button to enter bios, etc) but sure it's not worth taking apart the entire system, and paying the extra for the newer board.  Will stay with what I have.