<div dir="ltr">Hi all,<div><br></div><div>I have rapidly reviewed the source code of vtkImageReader and vtkImageReader2. My first impression is that in my own scenario vtkImageReader2 may run significantly slower than vtkImageReader because of this call in the inner for() loop (the one on rows) of method "vtkImageReader2Update()":</div>
<div><br></div><div>[...]</div><div><div>// seek to the correct row</div><div>self->SeekFile(outExtent[0],idx1,idx2);</div><div>[...]<br></div><div><br></div><div>It looks like the equivalent method in vtkImageReader does much fewer seek operations while reading the single large volume file (dimensionality = 3).</div>
<div>Just my first impression, I might be wrong.</div><div><br></div><div>I am looking forward to hearing your comments.</div><div>Thanks and best regards,</div><div><br></div><div>Marco Sambin</div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Fri, Jun 13, 2014 at 11:09 AM, Marco Sambin <span dir="ltr"><<a href="mailto:m.sambin@gmail.com" target="_blank">m.sambin@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">Hi all,<div><br></div><div>i repeated my tests with Little Endian byte ordering: both <span style="font-family:arial,sans-serif;font-size:13px">testVTKImageReader() and </span><span style="font-family:arial,sans-serif;font-size:13px">testVTKImageReader2() methods run around 5% - 10% faster, but </span><span style="font-family:arial,sans-serif;font-size:13px">testVTKImageReader() is consistently around 5 times faster than </span><span style="font-family:arial,sans-serif;font-size:13px">testVTKImageReader2().</span></div>

<div><span style="font-family:arial,sans-serif;font-size:13px">For your reference, my raw file volume is around 260 MB (521 slices, 512x512 pixels, unsigned short pixel values).</span></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br>

</span></div><div><span style="font-family:arial,sans-serif;font-size:13px">I will investigate further. If you have any clues, please let me know.</span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Of course, I could simply use vtkImageReader, which is much faster for me, but I was interested in understanding why there is such a huge performance difference between the two readers, in accomplishing a task which should be equivalent with the two readers.</span></div>

<div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Thanks and best regards,</span></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br>

</span></div><div><span style="font-family:arial,sans-serif;font-size:13px">Marco Sambin</span></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jun 12, 2014 at 8:06 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I made a major typo in my last email.  I meant to say "try<br>

repeating the tests with SetDataByteOrderToLittleEndian()"<br>
<br>
On Thu, Jun 12, 2014 at 11:55 AM, David Gobbi <<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>> wrote:<br>
> Hi Marco,<br>
><br>
> Try repeating the tests with SetDataByteOrderToBigEndian().  If the<br>
> byte reordering is really the most CPU-intensive part of the read, as<br>
> I suspect, then this should reduce both times but perhaps one more<br>
> than the other.<br>
><br>
> Other than that, I don't have any guesses.  In vtkImageReader.cxx, I<br>
> notice that it reads into a buffer where it performs the byte swap,<br>
> whereas vtkImageReader2.cxx doesn't use a buffer.  If this makes any<br>
> difference at all, though, it should be in favor of vtkImageReader2<br>
> (unless CPU cache misses are involved).<br>
><br>
> The only way to be sure is to run the tests in a C++ profiler, on OS X<br>
> I use "Instruments" but I've never done profiling on Windows.  On a<br>
> related note, one thing that I did find via profiling is that fread()<br>
> was 4x faster than doing read() on a C++ fstream.  But this was only<br>
> meaningful when reading from disk cache.  When the reads were hitting<br>
> the actual disk, the difference was negligible.<br>
><br>
>   David<br>
><br>
><br>
><br>
> On Thu, Jun 12, 2014 at 11:37 AM, Marco Sambin <<a href="mailto:m.sambin@gmail.com" target="_blank">m.sambin@gmail.com</a>> wrote:<br>
>> Hi David,<br>
>><br>
>> first of all, thank you for your reply.<br>
>> No, the difference is not related to disk caching issues. Here are two test<br>
>> methods that I've written:<br>
>><br>
>><br>
>> public static void testVTKImageReader()<br>
>>   {<br>
>>     long startTime = System.currentTimeMillis();<br>
>><br>
>>     vtkImageReader testReaderVTK =  new vtkImageReader();<br>
>>     testReaderVTK.FileLowerLeftOn();<br>
>>     testReaderVTK.SetFileDimensionality(3);<br>
>>     testReaderVTK.SetFileName("C:\\Test\\SeriesVolume.raw");<br>
>><br>
>>     testReaderVTK.SetDataExtent(0, 511,<br>
>>                           0, 511,<br>
>>                           0, 520);<br>
>>     testReaderVTK.SetDataSpacing(1.0, 1.0, 1.0);<br>
>>     testReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>>     testReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>>     testReaderVTK.SetDataByteOrderToBigEndian();<br>
>>     testReaderVTK.UpdateWholeExtent();<br>
>><br>
>>     long endTime = System.currentTimeMillis();<br>
>><br>
>>     System.out.println("Volume read by vtkImageReader. Total time millis = "<br>
>> + (endTime - startTime));<br>
>>   }<br>
>><br>
>>   public static void testVTKImageReader2()<br>
>>   {<br>
>>     long startTime = System.currentTimeMillis();<br>
>><br>
>>     vtkImageReader2 testReaderVTK =  new vtkImageReader2();<br>
>>     testReaderVTK.FileLowerLeftOn();<br>
>>     testReaderVTK.SetFileDimensionality(3);<br>
>>     testReaderVTK.SetFileName("C:\\Test\\SeriesVolume.raw");<br>
>><br>
>>     testReaderVTK.SetDataExtent(0, 511,<br>
>>                           0, 511,<br>
>>                           0, 520);<br>
>>     testReaderVTK.SetDataSpacing(1.0, 1.0, 1.0);<br>
>>     testReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>>     testReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>>     testReaderVTK.SetDataByteOrderToBigEndian();<br>
>>     testReaderVTK.UpdateWholeExtent();<br>
>><br>
>>     long endTime = System.currentTimeMillis();<br>
>><br>
>>     System.out.println("Volume read by vtkImageReader2. Total time millis =<br>
>> " + (endTime - startTime));<br>
>>   }<br>
>><br>
>> After doing a couple of "cold starts" in order to "warm up" disk caches, on<br>
>> my test PC method "testVTKImageReader()" executes in around 2 seconds, while<br>
>> method "testVTKImageReader2()" executes in around 10 seconds.<br>
>> I've tried executing testVTKImageReader() before and testVTKImageReader2()<br>
>> after or viceversa during the same execution session, but the result doesn't<br>
>> change: testVTKImageReader() is always around 5 times faster than<br>
>> testVTKImageReader2().<br>
>><br>
>> Can you guess why?<br>
>> Thanks and best regards,<br>
>><br>
>> Marco Sambin<br>
>><br>
>><br>
>><br>
>> On Thu, Jun 12, 2014 at 7:12 PM, David Gobbi <<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>> wrote:<br>
>>><br>
>>> Hi Marco,<br>
>>><br>
>>> When used the way they are in your example code, vtkImageReader and<br>
>>> vtkImageReader2 should be exactly the same speed.<br>
>>><br>
>>> Can you explain your testing methodology in more detail?  I suspect that<br>
>>> when you tested vtkImageReader2, it was reading from disk, and when<br>
>>> testing vtkImageReader, it was reading from disk cache.  The only part<br>
>>> of the "read" operation that actually requires any CPU time is the byte<br>
>>> swapping, but that should be identical for the two readers.<br>
>>><br>
>>>  - David<br>
>>><br>
>>><br>
>>> On Thu, Jun 12, 2014 at 11:00 AM, Marco Sambin <<a href="mailto:m.sambin@gmail.com" target="_blank">m.sambin@gmail.com</a>> wrote:<br>
>>> > Hi all.<br>
>>> > I am reading a volume made up of a set of "slices" stored in a single<br>
>>> > large<br>
>>> > raw file, containing just the raw pixels of each slice (unsigned short<br>
>>> > values), one slice after the other. I know in advance image size,<br>
>>> > position,<br>
>>> > orientation and spacing information related to each slice.<br>
>>> > I used to read my input raw volume through the vtkImageReader2 class, as<br>
>>> > documentation of vtkImageReader states:<br>
>>> ><br>
>>> > "vtkImageReader provides methods needed to read a region from a file. It<br>
>>> > supports both transforms and masks on the input data, but as a result is<br>
>>> > more complicated and slower than its parent class vtkImageReader2."<br>
>>> ><br>
>>> > so I always assumed vtkImageReader2 to be faster than vtkImageReader to<br>
>>> > read<br>
>>> > a simple volume made up of a set of raw slices.<br>
>>> > This until today, when I tried replacing my instance of vtkImageReader2<br>
>>> > with<br>
>>> > an instance of vtkImageReader. Guess what? My volume reading code now<br>
>>> > executes around 10 times faster!<br>
>>> ><br>
>>> > Is this expected? Can you guess what may be the reason for such a<br>
>>> > significant difference in performance between vtkImageReader2 and<br>
>>> > vtkImageReader, the latter being much faster in my scenario (despite<br>
>>> > what<br>
>>> > the documentation states)?<br>
>>> ><br>
>>> > For completeness, I am using VTK 6.1 64-bit from Java 7 64-bit, under<br>
>>> > Windows 7 Professional 64-bit. Here is a code fragment showing how I<br>
>>> > configure my reader:<br>
>>> ><br>
>>> > [...]<br>
>>> > imageReaderVTK =  new vtkImageReader(); // much slower if I use<br>
>>> > "vtkImageReader2" here<br>
>>> > imageReaderVTK.FileLowerLeftOn();<br>
>>> > imageReaderVTK.SetFileDimensionality(3);<br>
>>> > imageReaderVTK.SetFileName(curRawVolFile.getAbsolutePath());<br>
>>> > imageReaderVTK.SetDataExtent(0, sliceCols - 1,<br>
>>> >                       0, sliceRows - 1,<br>
>>> >                       0, numOfUsedImages - 1);<br>
>>> > imageReaderVTK.SetDataSpacing(xSpacing, ySpacing, zSpacing);<br>
>>> > imageReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>>> > imageReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>>> > imageReaderVTK.SetDataByteOrderToBigEndian();<br>
>>> > imageReaderVTK.UpdateWholeExtent();<br>
>>> > [...]<br>
>>> ><br>
>>> > My typical input raw volume is made up of around 500 slices, each one<br>
>>> > 512x512 pixels large.<br>
>>> ><br>
>>> > Thanks in advance for your feedback.<br>
>>> > Best regards,<br>
>>> ><br>
>>> > Marco Sambin<br>
>><br>
>><br>
</blockquote></div><br></div>
</blockquote></div><br></div></div></div>