NMVe SSD Fedora Throughput Tests too High

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












I am testing throughput of a Samsung 950 Pro SSD Card which uses NVMe protocol. My current method of testing is to mount a file system on a partition and write a file of size X bytes to the file system. By recording the time it takes to do so, the bytes/second can be calculated.



In my test, I have a while loop that will write up to the X bytes in variable block sizes, one block at a time, specified by a higher level for loop. On top of this, I also have another loop that will run N of these applications in parallel, each application writing to a different partition of the SSD.



Currently, I am seeing speeds slightly faster than the theoretical max transfer speed specified by the Samsung 950 Pro datasheet for both reading and writing. Samsung specified that the max sequential write speed for the 950 Pro is 1.5 GB/s and the max sequential read speed is 2.5 GB/s.



https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-950-pro-nvme-512gb-mz-v5p512bw/#specs



Here is the main function of the bash script that loops through the number of applications to run and block sizes:



appInstances=1
while [ $appInstances -le 4 ]
do
for blocksize in 4096 32768 131072 524288 1048576 67108864 268435456 1073741824
do
# Run the test
datetime
echo "[$datetime_v]: Test blocksize: $blocksize appInstances: $appInstances"
run_single_perf_test $blocksize

done

appInstances=`expr $appInstances * 2`

done
exit 0


Here is write section of run_perf_test. There is also a read section after this part, which comprises the writing throughput speed test. Between the tests, I unmount all partitions of the SSD and remount them to allow all NVMe transactions to complete and prevent any caching from writing operations to influence the throughput measurement for the reading operation.



instCnt=1
childpids=""
while [ $instCnt -le $appInstances ]
do
fsrw -w $blocksize /fsmnt/fs$instCnt/usernumber1/j.j &

# Save the process ID
childpids="$childpids $!"

# Increment the instace count.
instCnt=`expr $instCnt + 1`
done


fsrw is a C++ application that based on the first argument, "-r" or "-w", the second argument, the block size, and the third argument, the filename which is a file on the SSD partition, will build a string and attempt to open the file on the SSD partition and write the string to it. Here is the implementation for the write function, which is called when "-w" is provided as the first argument.



/*! fn perform_writeop()
* brief The function returns true when the write operation completes successfully.
*
* The function will run until the read is complete or a 35 second timeout is reached.
* It will record the time before the write begins, then also record the time afterward.
* If the timeout is reached this should be about 35 seconds
*/
bool perform_writeop ()
O_CREAT, 0660);

// Verify the file has been opened.
if (fd == -1)

cout << get_datetime_string() << "Write open of " << fname
<< " failed. Errno: " << errno << endl;

else

// Total bytes written.
uint64_t written = 0;

// Notify the start of the test.
cout << get_datetime_string() << "Write test started" << endl;

// Elapsed time.
struct timeval tv = 0 ;
get_elapsed_time (&tv);
struct timeval write_tv = tv;

// Run until it is time for the test to stop.
while (written < READ_LIMIT && zero_writes < 10)

ssize_t writesize = write (fd, &buf[0], blocksize);
if (writesize == -1)

cout << get_datetime_string << "Write failure. Errno: " << errno << endl;
zero_writes = 10;

else if (0 == writesize)

cout << get_datetime_string() << "Zero bytes written" << endl;
zero_writes++;

else

written += writesize;



string flush_command = "nvme flush /dev/nvme0n1p";
flush_command += fname[9];
system(flush_command.c_str());


// Get the elapsed time.
get_elapsed_time (&write_tv);

// Report the number of bytes written.
cout << get_datetime_string() << "Write " << written << " bytes in "
<< write_tv.tv_sec << "." << write_tv.tv_usec
<< " seconds" << endl;

// Close the file.
close (fd);

// Get the elapsed time.
get_elapsed_time (&tv);

// Report the number of bytes read.
cout << get_datetime_string() << "Write closed. " << written
<< " Bytes written in " << tv.tv_sec << "." << tv.tv_usec
<< " seconds" << endl;

// Report the number of bytes per second.
cout << get_datetime_string() << "Bytes per second "
<< bytes_per_second (&tv, written) << endl;

// Report the cache flush time.
struct timeval flush_tv = 0 ;
timersub (&tv, &write_tv, &flush_tv);
cout << get_datetime_string() << "System cache flush completed in "
<< flush_tv.tv_sec << "." << flush_tv.tv_usec << "seconds" << endl;

// Set the function return status when all write operations have
// been successful.
if (zero_writes < 10)

status = true;


return status;



The data I am getting back looks like this
enter image description here



The numbers are close to the maximum theoretical throughputs of the Samsung 950 Pro but some are too high and this troubles me. Why might I be getting numbers higher than the theoretical maximum throughput for the Samsung 950 Pro?







share|improve this question


























    up vote
    1
    down vote

    favorite












    I am testing throughput of a Samsung 950 Pro SSD Card which uses NVMe protocol. My current method of testing is to mount a file system on a partition and write a file of size X bytes to the file system. By recording the time it takes to do so, the bytes/second can be calculated.



    In my test, I have a while loop that will write up to the X bytes in variable block sizes, one block at a time, specified by a higher level for loop. On top of this, I also have another loop that will run N of these applications in parallel, each application writing to a different partition of the SSD.



    Currently, I am seeing speeds slightly faster than the theoretical max transfer speed specified by the Samsung 950 Pro datasheet for both reading and writing. Samsung specified that the max sequential write speed for the 950 Pro is 1.5 GB/s and the max sequential read speed is 2.5 GB/s.



    https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-950-pro-nvme-512gb-mz-v5p512bw/#specs



    Here is the main function of the bash script that loops through the number of applications to run and block sizes:



    appInstances=1
    while [ $appInstances -le 4 ]
    do
    for blocksize in 4096 32768 131072 524288 1048576 67108864 268435456 1073741824
    do
    # Run the test
    datetime
    echo "[$datetime_v]: Test blocksize: $blocksize appInstances: $appInstances"
    run_single_perf_test $blocksize

    done

    appInstances=`expr $appInstances * 2`

    done
    exit 0


    Here is write section of run_perf_test. There is also a read section after this part, which comprises the writing throughput speed test. Between the tests, I unmount all partitions of the SSD and remount them to allow all NVMe transactions to complete and prevent any caching from writing operations to influence the throughput measurement for the reading operation.



    instCnt=1
    childpids=""
    while [ $instCnt -le $appInstances ]
    do
    fsrw -w $blocksize /fsmnt/fs$instCnt/usernumber1/j.j &

    # Save the process ID
    childpids="$childpids $!"

    # Increment the instace count.
    instCnt=`expr $instCnt + 1`
    done


    fsrw is a C++ application that based on the first argument, "-r" or "-w", the second argument, the block size, and the third argument, the filename which is a file on the SSD partition, will build a string and attempt to open the file on the SSD partition and write the string to it. Here is the implementation for the write function, which is called when "-w" is provided as the first argument.



    /*! fn perform_writeop()
    * brief The function returns true when the write operation completes successfully.
    *
    * The function will run until the read is complete or a 35 second timeout is reached.
    * It will record the time before the write begins, then also record the time afterward.
    * If the timeout is reached this should be about 35 seconds
    */
    bool perform_writeop ()
    O_CREAT, 0660);

    // Verify the file has been opened.
    if (fd == -1)

    cout << get_datetime_string() << "Write open of " << fname
    << " failed. Errno: " << errno << endl;

    else

    // Total bytes written.
    uint64_t written = 0;

    // Notify the start of the test.
    cout << get_datetime_string() << "Write test started" << endl;

    // Elapsed time.
    struct timeval tv = 0 ;
    get_elapsed_time (&tv);
    struct timeval write_tv = tv;

    // Run until it is time for the test to stop.
    while (written < READ_LIMIT && zero_writes < 10)

    ssize_t writesize = write (fd, &buf[0], blocksize);
    if (writesize == -1)

    cout << get_datetime_string << "Write failure. Errno: " << errno << endl;
    zero_writes = 10;

    else if (0 == writesize)

    cout << get_datetime_string() << "Zero bytes written" << endl;
    zero_writes++;

    else

    written += writesize;



    string flush_command = "nvme flush /dev/nvme0n1p";
    flush_command += fname[9];
    system(flush_command.c_str());


    // Get the elapsed time.
    get_elapsed_time (&write_tv);

    // Report the number of bytes written.
    cout << get_datetime_string() << "Write " << written << " bytes in "
    << write_tv.tv_sec << "." << write_tv.tv_usec
    << " seconds" << endl;

    // Close the file.
    close (fd);

    // Get the elapsed time.
    get_elapsed_time (&tv);

    // Report the number of bytes read.
    cout << get_datetime_string() << "Write closed. " << written
    << " Bytes written in " << tv.tv_sec << "." << tv.tv_usec
    << " seconds" << endl;

    // Report the number of bytes per second.
    cout << get_datetime_string() << "Bytes per second "
    << bytes_per_second (&tv, written) << endl;

    // Report the cache flush time.
    struct timeval flush_tv = 0 ;
    timersub (&tv, &write_tv, &flush_tv);
    cout << get_datetime_string() << "System cache flush completed in "
    << flush_tv.tv_sec << "." << flush_tv.tv_usec << "seconds" << endl;

    // Set the function return status when all write operations have
    // been successful.
    if (zero_writes < 10)

    status = true;


    return status;



    The data I am getting back looks like this
    enter image description here



    The numbers are close to the maximum theoretical throughputs of the Samsung 950 Pro but some are too high and this troubles me. Why might I be getting numbers higher than the theoretical maximum throughput for the Samsung 950 Pro?







    share|improve this question
























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am testing throughput of a Samsung 950 Pro SSD Card which uses NVMe protocol. My current method of testing is to mount a file system on a partition and write a file of size X bytes to the file system. By recording the time it takes to do so, the bytes/second can be calculated.



      In my test, I have a while loop that will write up to the X bytes in variable block sizes, one block at a time, specified by a higher level for loop. On top of this, I also have another loop that will run N of these applications in parallel, each application writing to a different partition of the SSD.



      Currently, I am seeing speeds slightly faster than the theoretical max transfer speed specified by the Samsung 950 Pro datasheet for both reading and writing. Samsung specified that the max sequential write speed for the 950 Pro is 1.5 GB/s and the max sequential read speed is 2.5 GB/s.



      https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-950-pro-nvme-512gb-mz-v5p512bw/#specs



      Here is the main function of the bash script that loops through the number of applications to run and block sizes:



      appInstances=1
      while [ $appInstances -le 4 ]
      do
      for blocksize in 4096 32768 131072 524288 1048576 67108864 268435456 1073741824
      do
      # Run the test
      datetime
      echo "[$datetime_v]: Test blocksize: $blocksize appInstances: $appInstances"
      run_single_perf_test $blocksize

      done

      appInstances=`expr $appInstances * 2`

      done
      exit 0


      Here is write section of run_perf_test. There is also a read section after this part, which comprises the writing throughput speed test. Between the tests, I unmount all partitions of the SSD and remount them to allow all NVMe transactions to complete and prevent any caching from writing operations to influence the throughput measurement for the reading operation.



      instCnt=1
      childpids=""
      while [ $instCnt -le $appInstances ]
      do
      fsrw -w $blocksize /fsmnt/fs$instCnt/usernumber1/j.j &

      # Save the process ID
      childpids="$childpids $!"

      # Increment the instace count.
      instCnt=`expr $instCnt + 1`
      done


      fsrw is a C++ application that based on the first argument, "-r" or "-w", the second argument, the block size, and the third argument, the filename which is a file on the SSD partition, will build a string and attempt to open the file on the SSD partition and write the string to it. Here is the implementation for the write function, which is called when "-w" is provided as the first argument.



      /*! fn perform_writeop()
      * brief The function returns true when the write operation completes successfully.
      *
      * The function will run until the read is complete or a 35 second timeout is reached.
      * It will record the time before the write begins, then also record the time afterward.
      * If the timeout is reached this should be about 35 seconds
      */
      bool perform_writeop ()
      O_CREAT, 0660);

      // Verify the file has been opened.
      if (fd == -1)

      cout << get_datetime_string() << "Write open of " << fname
      << " failed. Errno: " << errno << endl;

      else

      // Total bytes written.
      uint64_t written = 0;

      // Notify the start of the test.
      cout << get_datetime_string() << "Write test started" << endl;

      // Elapsed time.
      struct timeval tv = 0 ;
      get_elapsed_time (&tv);
      struct timeval write_tv = tv;

      // Run until it is time for the test to stop.
      while (written < READ_LIMIT && zero_writes < 10)

      ssize_t writesize = write (fd, &buf[0], blocksize);
      if (writesize == -1)

      cout << get_datetime_string << "Write failure. Errno: " << errno << endl;
      zero_writes = 10;

      else if (0 == writesize)

      cout << get_datetime_string() << "Zero bytes written" << endl;
      zero_writes++;

      else

      written += writesize;



      string flush_command = "nvme flush /dev/nvme0n1p";
      flush_command += fname[9];
      system(flush_command.c_str());


      // Get the elapsed time.
      get_elapsed_time (&write_tv);

      // Report the number of bytes written.
      cout << get_datetime_string() << "Write " << written << " bytes in "
      << write_tv.tv_sec << "." << write_tv.tv_usec
      << " seconds" << endl;

      // Close the file.
      close (fd);

      // Get the elapsed time.
      get_elapsed_time (&tv);

      // Report the number of bytes read.
      cout << get_datetime_string() << "Write closed. " << written
      << " Bytes written in " << tv.tv_sec << "." << tv.tv_usec
      << " seconds" << endl;

      // Report the number of bytes per second.
      cout << get_datetime_string() << "Bytes per second "
      << bytes_per_second (&tv, written) << endl;

      // Report the cache flush time.
      struct timeval flush_tv = 0 ;
      timersub (&tv, &write_tv, &flush_tv);
      cout << get_datetime_string() << "System cache flush completed in "
      << flush_tv.tv_sec << "." << flush_tv.tv_usec << "seconds" << endl;

      // Set the function return status when all write operations have
      // been successful.
      if (zero_writes < 10)

      status = true;


      return status;



      The data I am getting back looks like this
      enter image description here



      The numbers are close to the maximum theoretical throughputs of the Samsung 950 Pro but some are too high and this troubles me. Why might I be getting numbers higher than the theoretical maximum throughput for the Samsung 950 Pro?







      share|improve this question














      I am testing throughput of a Samsung 950 Pro SSD Card which uses NVMe protocol. My current method of testing is to mount a file system on a partition and write a file of size X bytes to the file system. By recording the time it takes to do so, the bytes/second can be calculated.



      In my test, I have a while loop that will write up to the X bytes in variable block sizes, one block at a time, specified by a higher level for loop. On top of this, I also have another loop that will run N of these applications in parallel, each application writing to a different partition of the SSD.



      Currently, I am seeing speeds slightly faster than the theoretical max transfer speed specified by the Samsung 950 Pro datasheet for both reading and writing. Samsung specified that the max sequential write speed for the 950 Pro is 1.5 GB/s and the max sequential read speed is 2.5 GB/s.



      https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-950-pro-nvme-512gb-mz-v5p512bw/#specs



      Here is the main function of the bash script that loops through the number of applications to run and block sizes:



      appInstances=1
      while [ $appInstances -le 4 ]
      do
      for blocksize in 4096 32768 131072 524288 1048576 67108864 268435456 1073741824
      do
      # Run the test
      datetime
      echo "[$datetime_v]: Test blocksize: $blocksize appInstances: $appInstances"
      run_single_perf_test $blocksize

      done

      appInstances=`expr $appInstances * 2`

      done
      exit 0


      Here is write section of run_perf_test. There is also a read section after this part, which comprises the writing throughput speed test. Between the tests, I unmount all partitions of the SSD and remount them to allow all NVMe transactions to complete and prevent any caching from writing operations to influence the throughput measurement for the reading operation.



      instCnt=1
      childpids=""
      while [ $instCnt -le $appInstances ]
      do
      fsrw -w $blocksize /fsmnt/fs$instCnt/usernumber1/j.j &

      # Save the process ID
      childpids="$childpids $!"

      # Increment the instace count.
      instCnt=`expr $instCnt + 1`
      done


      fsrw is a C++ application that based on the first argument, "-r" or "-w", the second argument, the block size, and the third argument, the filename which is a file on the SSD partition, will build a string and attempt to open the file on the SSD partition and write the string to it. Here is the implementation for the write function, which is called when "-w" is provided as the first argument.



      /*! fn perform_writeop()
      * brief The function returns true when the write operation completes successfully.
      *
      * The function will run until the read is complete or a 35 second timeout is reached.
      * It will record the time before the write begins, then also record the time afterward.
      * If the timeout is reached this should be about 35 seconds
      */
      bool perform_writeop ()
      O_CREAT, 0660);

      // Verify the file has been opened.
      if (fd == -1)

      cout << get_datetime_string() << "Write open of " << fname
      << " failed. Errno: " << errno << endl;

      else

      // Total bytes written.
      uint64_t written = 0;

      // Notify the start of the test.
      cout << get_datetime_string() << "Write test started" << endl;

      // Elapsed time.
      struct timeval tv = 0 ;
      get_elapsed_time (&tv);
      struct timeval write_tv = tv;

      // Run until it is time for the test to stop.
      while (written < READ_LIMIT && zero_writes < 10)

      ssize_t writesize = write (fd, &buf[0], blocksize);
      if (writesize == -1)

      cout << get_datetime_string << "Write failure. Errno: " << errno << endl;
      zero_writes = 10;

      else if (0 == writesize)

      cout << get_datetime_string() << "Zero bytes written" << endl;
      zero_writes++;

      else

      written += writesize;



      string flush_command = "nvme flush /dev/nvme0n1p";
      flush_command += fname[9];
      system(flush_command.c_str());


      // Get the elapsed time.
      get_elapsed_time (&write_tv);

      // Report the number of bytes written.
      cout << get_datetime_string() << "Write " << written << " bytes in "
      << write_tv.tv_sec << "." << write_tv.tv_usec
      << " seconds" << endl;

      // Close the file.
      close (fd);

      // Get the elapsed time.
      get_elapsed_time (&tv);

      // Report the number of bytes read.
      cout << get_datetime_string() << "Write closed. " << written
      << " Bytes written in " << tv.tv_sec << "." << tv.tv_usec
      << " seconds" << endl;

      // Report the number of bytes per second.
      cout << get_datetime_string() << "Bytes per second "
      << bytes_per_second (&tv, written) << endl;

      // Report the cache flush time.
      struct timeval flush_tv = 0 ;
      timersub (&tv, &write_tv, &flush_tv);
      cout << get_datetime_string() << "System cache flush completed in "
      << flush_tv.tv_sec << "." << flush_tv.tv_usec << "seconds" << endl;

      // Set the function return status when all write operations have
      // been successful.
      if (zero_writes < 10)

      status = true;


      return status;



      The data I am getting back looks like this
      enter image description here



      The numbers are close to the maximum theoretical throughputs of the Samsung 950 Pro but some are too high and this troubles me. Why might I be getting numbers higher than the theoretical maximum throughput for the Samsung 950 Pro?









      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 29 '17 at 15:57









      Jeff Schaller

      32.1k849109




      32.1k849109










      asked Nov 29 '17 at 13:58









      John Frye

      161




      161

























          active

          oldest

          votes











          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f407748%2fnmve-ssd-fedora-throughput-tests-too-high%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f407748%2fnmve-ssd-fedora-throughput-tests-too-high%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Peggy Mitchell

          Palaiologos

          The Forum (Inglewood, California)