Example #1
0
void
run_all (FILE *fp)
{
  mp_size_t  prev_size;
  int        i;
  TMP_DECL;

  TMP_MARK;
  SPEED_TMP_ALLOC_LIMBS (sp.xp_block, SPEED_BLOCK_SIZE, sp.align_xp);
  SPEED_TMP_ALLOC_LIMBS (sp.yp_block, SPEED_BLOCK_SIZE, sp.align_yp);

  data_fill (sp.xp_block, SPEED_BLOCK_SIZE);
  data_fill (sp.yp_block, SPEED_BLOCK_SIZE);

  for (i = 0; i < size_num; i++)
    {
      sp.size = size_array[i].start;
      prev_size = -1;
      for (;;)
        {
          mp_size_t  step;

          if (option_data == DATA_2FD && sp.size >= 2)
            sp.xp[sp.size-1] = 2;

          run_one (fp, &sp, prev_size);
          prev_size = sp.size;

          if (option_data == DATA_2FD && sp.size >= 2)
            sp.xp[sp.size-1] = MP_LIMB_T_MAX;

          if (option_factor != 0.0)
            {
              step = (mp_size_t) (sp.size * option_factor - sp.size);
              if (step < 1)
                step = 1;
            }
          else if(size_array[i].inc > 0)
              step = size_array[i].inc;
          else
            step = 1;

          if (step < option_step)
            step = option_step;

          sp.size += step;
          if (sp.size > size_array[i].end)
            break;
        }
    }

  TMP_FREE;
}
Example #2
0
    // Try allocating two filemaps and try a data_fill that
    // crosses the boundary between them
    void test_file_boundary() {
        const int test_filemap1 = 1;
        const int test_filemap2 = 2;
        const int test_clusters = 3;
        uint32_t clust_nr1 = fat_alloc_filemap(test_filemap1, test_clusters);
        uint32_t clust_nr2 = fat_alloc_filemap(test_filemap2, test_clusters);

        // Check that they were allocated next to each other
        QCOMPARE(clust_nr2, clust_nr1 - test_clusters);

        fat_finalize(DATA_CLUSTERS);

        int ret = data_fill(datapage, 4096, clust_nr1 - 1, 512, &filled);
        QCOMPARE(ret, 0);
        const uint32_t expected_end = 4096 - 512;
        const uint32_t expected_offset = (test_clusters - 1) * 4096 + 512;
        // data_fill is allowed to go past the end of the cluster,
        // but doesn't have to.
        QVERIFY(filled >= expected_end);
        QVERIFY(filled <= 4096);
        check_fill(datapage, MOCK_FILEMAP_FILL, expected_end, test_filemap2,
                expected_offset);
        if (filled > expected_end) {
            check_fill(datapage + expected_end, MOCK_FILEMAP_FILL,
                    filled - expected_end, test_filemap1, 0);
        }
    }
Example #3
0
    // Try allocating one filemap and check the result
    void test_one_filemap() {
        const int test_filemap = 8;
        const int test_clusters = 17;
        const uint32_t expected_entry = FAT_ENTRIES - test_clusters;

        uint32_t clust_nr = fat_alloc_filemap(test_filemap, test_clusters);
        // Check that filemap was allocated at the end of the image
        QCOMPARE(clust_nr, expected_entry);

        fat_finalize(DATA_CLUSTERS);

        // Check that the last fat page shows the file
        uint32_t *buf = (uint32_t *) alloc_guarded(
                (test_clusters + 2) * sizeof(uint32_t));
        fat_fill(buf, expected_entry - 1, test_clusters + 2);
        QCOMPARE(buf[0], (uint32_t) 0); // empty before file
        // ascending chain except last entry
        for (uint32_t i = 0; i < test_clusters - 1; i++) {
            QCOMPARE(buf[i + 1], expected_entry + i + 1);
        }
        // end of chain marker
        QCOMPARE(buf[test_clusters], (uint32_t) 0x0fffffff);
        // bad cluster marker after file (because it's at the end of
        // allocatable space)
        QCOMPARE(buf[test_clusters + 1], (uint32_t) 0x0ffffff7);

        // Check that an arbitrary cluster can be loaded from the file
        int ret = data_fill(datapage, 4096, expected_entry + 3, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        check_fill(datapage, MOCK_FILEMAP_FILL, 4096, test_filemap, 3 * 4096);
    }
Example #4
0
    void test_bad_args() {
        QCOMPARE(fat_extend(0, 1), false);
        QCOMPARE(fat_extend(FAT_ENTRIES, 1), false);

        fat_finalize(DATA_CLUSTERS);

        int ret = data_fill(datapage, 4096, FAT_ENTRIES, 0, &filled);
        QCOMPARE(ret, EINVAL);
    }
Example #5
0
    void test_empty_fat() {
        // No dirs should be found
        QCOMPARE(fat_dir_index(0), -1);
        QCOMPARE(fat_dir_index(1000), -1);

        fat_finalize(DATA_CLUSTERS); // required by API

        fat_fill(fatpage, 0, 1024);
        // Check the special first two fat entries
        QCOMPARE(fatpage[0], (uint32_t) 0x0ffffff8); // media byte marker
        QCOMPARE(fatpage[1], (uint32_t) 0x0fffffff); // end of chain marker
        VERIFY_ARRAY(fatpage, 2, 1024, (uint32_t) 0);

        int ret = data_fill(datapage, 4096, 2, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        VERIFY_ARRAY(datapage, 0, 4096, (char) 0);
    }
Example #6
0
    // Try allocating one directory and check the result
    void test_one_dir() {
        const int test_dir_index = 5;
        uint32_t clust_nr = fat_alloc_dir(test_dir_index);
        QCOMPARE(clust_nr, (uint32_t) 2);
        QCOMPARE(fat_dir_index(0), -1);
        QCOMPARE(fat_dir_index(1), -1);
        QCOMPARE(fat_dir_index(2), test_dir_index);
        QCOMPARE(fat_dir_index(3), -1);
        QCOMPARE(fat_dir_index(4), -1);

        fat_finalize(DATA_CLUSTERS);

        // Check that fat_finalize didn't mess up the entries
        QCOMPARE(fat_dir_index(0), -1);
        QCOMPARE(fat_dir_index(1), -1);
        QCOMPARE(fat_dir_index(2), test_dir_index);
        QCOMPARE(fat_dir_index(3), -1);
        QCOMPARE(fat_dir_index(4), -1);

        // Check that the first fat page shows the directory
        fat_fill(fatpage, 0, 1024);
        // Check the special first two fat entries
        QCOMPARE(fatpage[0], (uint32_t) 0x0ffffff8); // media byte marker
        QCOMPARE(fatpage[1], (uint32_t) 0x0fffffff); // end of chain marker
        // Check the new directory entry
        QCOMPARE(fatpage[2], (uint32_t) 0x0fffffff); // end of chain marker
        VERIFY_ARRAY(fatpage, 3, 1024, (uint32_t) 0); // everything else 0

        // Check that data_fill accesses the directory
        int ret = data_fill(datapage, 8192, 2, 0, &filled);
        QCOMPARE(ret, 0);
        // Check that the whole directory cluster was filled
        QVERIFY2(filled >= 4096, QTest::toString(filled));
        // Check that dir_fill did the filling
        check_fill(datapage, MOCK_DIR_FILL, 4096, test_dir_index, 0);
        // and any extra fill is from an empty cluster
        // (current code does not fill more than the dir but it's allowed to)
        VERIFY_ARRAY(datapage, 4096, (int) filled, (char) 0);
    }
Example #7
0
void
run_one (FILE *fp, struct speed_params *s, mp_size_t prev_size)
{
  const char  *first_open_fastest, *first_open_notfastest, *first_close;
  int         j,i, fastest, want_data;
  double      fastest_time;
  TMP_DECL;

  TMP_MARK;

  /* allocate data, unless all routines are NODATA */
  want_data = 0;
  for (i = 0; i < num_choices; i++)
    want_data |= ((choice[i].p->flag & FLAG_NODATA) == 0);

  if (want_data)
    {
      SPEED_TMP_ALLOC_LIMBS (sp.xp, s->size, s->align_xp);
      SPEED_TMP_ALLOC_LIMBS (sp.yp, s->size, s->align_yp);

      data_fill (s->xp, s->size);
      data_fill (s->yp, s->size);
    }
  else
    {
      sp.xp = NULL;
      sp.yp = NULL;
    }

  if (prev_size == -1 && option_cmp == CMP_DIFFPREV)
    {
      first_open_fastest = "(#";
      first_open_notfastest = " (";
      first_close = ")";
    }
  else
    {
      first_open_fastest = "#";
      first_open_notfastest = " ";
      first_close = "";
    }

  fastest = -1;
  fastest_time = -1.0;
  for (i = 0; i < num_choices; i++)
    {
      if( choice[i].nsum!=0)continue;
      s->r = choice[i].r;
      if( choice[i].colfile==-1)
        {choice[i].time = speed_measure (choice[i].p->fun, s);}
      else
        {FILE *fp;char buf[1024],buf2[1024],*p;int got=0;
         choice[i].time=-1.0;
         fp=fopen(choice[i].filename,"rt");
         if(fp==0){printf("Cant open %s\n",choice[i].filename);exit(1);}
         while(fgets(buf,1024,fp)!=0)
              if(atoi(buf)==s->size)
                {p=buf;
                 for(j=0;j<=choice[i].colfile;j++)
                    {if(sscanf(p," %s",buf2)!=1)break;                
                     p=strstr(p,buf2)+strlen(buf2);}
                 if(j==choice[i].colfile+1)
                   {while((p=strstr(buf2,"#"))!=0)*p=' ';// exclude #
                    choice[i].time=atof(buf2);                  
                   }         
                 break;}
         fclose(fp);
         }
      choice[i].no_time = (choice[i].time == -1.0);
      if (! choice[i].no_time)
        choice[i].time *= choice[i].scale;

      /* Apply the effect of CMP_DIFFPREV, but the new choice[i].prev_time
         is before any differences.  */
      if(choice[i].colfile==-1)   
      {
        double     t;
        t = choice[i].time;
        if (t != -1.0 && option_cmp == CMP_DIFFPREV && prev_size != -1)
          {
            if (choice[i].prev_time == -1.0)
              choice[i].no_time = 1;
            else
              choice[i].time = choice[i].time - choice[i].prev_time;
          }
        choice[i].prev_time = t;
      }

    }
  for (i = 0; i < num_choices; i++)
     {if(choice[i].nsum==0)continue;
      choice[i].time=0;choice[i].no_time=0;
      for(j=0;j<choice[i].nsum;j++)
         {choice[i].time+=choice[choice[i].sum[j]].time;
          if(choice[choice[i].sum[j]].no_time)choice[i].no_time=1;
         }
     }

  for (i = 0; i < num_choices; i++)
    {
      if (choice[i].no_time || choice[i].colfile!=-1)
        continue;
      if (option_cmp == CMP_DIFFPREV)
        {
          /* Conversion for UNIT_CYCLESPERLIMB differs in CMP_DIFFPREV. */
          if (option_unit == UNIT_CYCLES)
            choice[i].time /= speed_cycletime;
          else if (option_unit == UNIT_CYCLESPERLIMB)
            {
              if (prev_size == -1)
                choice[i].time /= speed_cycletime;
              else
                choice[i].time /=  (speed_cycletime
                                    * (SIZE_TO_DIVISOR(s->size)
                                       - SIZE_TO_DIVISOR(prev_size)));
            }
        }
      else
        {
          if (option_unit == UNIT_CYCLES)
            choice[i].time /= speed_cycletime;
          else if (option_unit == UNIT_CYCLESPERLIMB)
            choice[i].time /= (speed_cycletime * SIZE_TO_DIVISOR(s->size));
        }
    }    
  for (i = 0; i < num_choices; i++)
    {
      if (choice[i].no_time)
        continue;

      /* Look for the fastest after CMP_DIFFPREV has been applied, but
         before CMP_RATIO or CMP_DIFFERENCE.  There's only a fastest shown
         if there's more than one routine.  */
      for(j=0;j<xcoln;j++)if(xcol[j]==i)break;   // excluded from fastest choice
      if (j==xcoln && num_choices > 1 && (fastest == -1 || choice[i].time < fastest_time))
        {
          fastest = i;
          fastest_time = choice[i].time;
        }
    }

  for (i = 0; i < num_choices; i++)
    {
      if (choice[i].no_time )
        continue;

      if (option_cmp != CMP_DIFFPREV)
        {
        
          if (option_cmp == CMP_RATIO && i != option_cmp_pos)
            {
              /* A ratio isn't affected by the units chosen. */
              if (choice[option_cmp_pos].no_time || choice[option_cmp_pos].time == 0.0)
                choice[i].no_time = 1;
              else
                choice[i].time /= choice[option_cmp_pos].time;
            }
          else if (option_cmp == CMP_DIFFERENCE && i != option_cmp_pos)
            {
              if (choice[option_cmp_pos].no_time)
                {
                  choice[i].no_time = 1;
                  continue;
                }
              choice[i].time -= choice[option_cmp_pos].time;
            }
        }
    }

  if (option_gnuplot)
    {
      /* In CMP_DIFFPREV, don't print anything for the first size, start
         with the second where an actual difference is available.

         In CMP_RATIO, print the "first" ie option_cmp_pos column as 1.0.

         The 9 decimals printed is much more than the expected precision of
         the measurements actually. */

      if (! (option_cmp == CMP_DIFFPREV && prev_size == -1))
        {
          fprintf (fp, "%-6ld ", s->size);
          for (i = 0; i < num_choices; i++)
            fprintf (fp, "  %.9e",
                     choice[i].no_time ? 0.0
                     : (option_cmp == CMP_RATIO && i == option_cmp_pos) ? 1.0
                     : choice[i].time);
          fprintf (fp, "\n");
        }
    }
  else
    {
      fprintf (fp, "%-6ld ", s->size);
      for (i = 0; i < num_choices; i++)
        {
          char  buf[128];
          int   decimals;

          if (choice[i].no_time)
            {
              fprintf (fp, " %*s", COLUMN_WIDTH, "n/a");
            }
          else
            {if (option_unit == UNIT_CYCLESPERLIMB
                 || (option_cmp == CMP_RATIO && i != option_cmp_pos))
                decimals = 4;
              else if (option_unit == UNIT_CYCLES)
                decimals = 2;
              else
                decimals = 9;

              sprintf (buf, "%s%.*f%s",
                       i == fastest ? first_open_fastest : first_open_notfastest,
                       decimals, choice[i].time, first_close);
              fprintf (fp, " %*s", COLUMN_WIDTH, buf);
            }
        }
      fprintf (fp, "\n");
    }

  TMP_FREE;
}
Example #8
0
File: speed.c Project: Cl3Kener/gmp
void
run_one (FILE *fp, struct speed_params *s, mp_size_t prev_size)
{
  const char  *first_open_fastest, *first_open_notfastest, *first_close;
  int         i, fastest, want_data;
  double      fastest_time;
  TMP_DECL;

  TMP_MARK;

  /* allocate data, unless all routines are NODATA */
  want_data = 0;
  for (i = 0; i < num_choices; i++)
    want_data |= ((choice[i].p->flag & FLAG_NODATA) == 0);

  if (want_data)
    {
      SPEED_TMP_ALLOC_LIMBS (sp.xp, s->size, s->align_xp);
      SPEED_TMP_ALLOC_LIMBS (sp.yp, s->size, s->align_yp);

      data_fill (s->xp, s->size);
      data_fill (s->yp, s->size);
    }
  else
    {
      sp.xp = NULL;
      sp.yp = NULL;
    }

  if (prev_size == -1 && option_cmp == CMP_DIFFPREV)
    {
      first_open_fastest = "(#";
      first_open_notfastest = " (";
      first_close = ")";
    }
  else
    {
      first_open_fastest = "#";
      first_open_notfastest = " ";
      first_close = "";
    }

  fastest = -1;
  fastest_time = -1.0;
  for (i = 0; i < num_choices; i++)
    {
      s->r = choice[i].r;
      choice[i].time = speed_measure (choice[i].p->fun, s);
      choice[i].no_time = (choice[i].time == -1.0);
      if (! choice[i].no_time)
        choice[i].time *= choice[i].scale;

      /* Apply the effect of CMP_DIFFPREV, but the new choice[i].prev_time
         is before any differences.  */
      {
        double     t;
        t = choice[i].time;
        if (t != -1.0 && option_cmp == CMP_DIFFPREV && prev_size != -1)
          {
            if (choice[i].prev_time == -1.0)
              choice[i].no_time = 1;
            else
              choice[i].time = choice[i].time - choice[i].prev_time;
          }
        choice[i].prev_time = t;
      }

      if (choice[i].no_time)
        continue;

      /* Look for the fastest after CMP_DIFFPREV has been applied, but
         before CMP_RATIO or CMP_DIFFERENCE.  There's only a fastest shown
         if there's more than one routine.  */
      if (num_choices > 1 && (fastest == -1 || choice[i].time < fastest_time))
        {
          fastest = i;
          fastest_time = choice[i].time;
        }

      if (option_cmp == CMP_DIFFPREV)
        {
          /* Conversion for UNIT_CYCLESPERLIMB differs in CMP_DIFFPREV. */
          if (option_unit == UNIT_CYCLES)
            choice[i].time /= speed_cycletime;
          else if (option_unit == UNIT_CYCLESPERLIMB)
            {
              if (prev_size == -1)
                choice[i].time /= speed_cycletime;
              else
                choice[i].time /=  (speed_cycletime
                                    * (SIZE_TO_DIVISOR(s->size)
                                       - SIZE_TO_DIVISOR(prev_size)));
            }
        }
      else
        {
          if (option_unit == UNIT_CYCLES)
            choice[i].time /= speed_cycletime;
          else if (option_unit == UNIT_CYCLESPERLIMB)
            choice[i].time /= (speed_cycletime * SIZE_TO_DIVISOR(s->size));

          if (option_cmp == CMP_RATIO && i > 0)
            {
              /* A ratio isn't affected by the units chosen. */
              if (choice[0].no_time || choice[0].time == 0.0)
                choice[i].no_time = 1;
              else
                choice[i].time /= choice[0].time;
            }
          else if (option_cmp == CMP_DIFFERENCE && i > 0)
            {
              if (choice[0].no_time)
                {
                  choice[i].no_time = 1;
                  continue;
                }
              choice[i].time -= choice[0].time;
            }
        }
    }

  if (option_gnuplot)
    {
      /* In CMP_DIFFPREV, don't print anything for the first size, start
         with the second where an actual difference is available.

         In CMP_RATIO, print the first column as 1.0.

         The 9 decimals printed is much more than the expected precision of
         the measurements actually. */

      if (! (option_cmp == CMP_DIFFPREV && prev_size == -1))
        {
          fprintf (fp, "%-6ld ", s->size);
          for (i = 0; i < num_choices; i++)
            fprintf (fp, "  %.9e",
                     choice[i].no_time ? 0.0
                     : (option_cmp == CMP_RATIO && i == 0) ? 1.0
                     : choice[i].time);
          fprintf (fp, "\n");
        }
    }
  else
    {
      fprintf (fp, "%-6ld ", s->size);
      for (i = 0; i < num_choices; i++)
        {
          char  buf[128];
          int   decimals;

          if (choice[i].no_time)
            {
              fprintf (fp, " %*s", COLUMN_WIDTH, "n/a");
            }
          else
            {if (option_unit == UNIT_CYCLESPERLIMB
                 || (option_cmp == CMP_RATIO && i > 0))
                decimals = 4;
              else if (option_unit == UNIT_CYCLES)
                decimals = 2;
              else
                decimals = 9;

              sprintf (buf, "%s%.*f%s",
                       i == fastest ? first_open_fastest : first_open_notfastest,
                       decimals, choice[i].time, first_close);
              fprintf (fp, " %*s", COLUMN_WIDTH, buf);
            }
        }
      fprintf (fp, "\n");
    }

  TMP_FREE;
}
Example #9
0
    // Try allocating two directories and then extending the first twice
    void test_extend_dir_twice() {
        const int test_dir_index1 = 7;
        const int test_dir_index2 = 11;

        uint32_t clust_nr1 = fat_alloc_dir(test_dir_index1);
        uint32_t clust_nr2 = fat_alloc_dir(test_dir_index2);

        QCOMPARE(clust_nr1, (uint32_t) 2);
        QCOMPARE(clust_nr2, (uint32_t) 3);

        bool ret1 = fat_extend(clust_nr1, 1);
        QCOMPARE(ret1, true);
        bool ret2 = fat_extend(clust_nr1, 1);
        QCOMPARE(ret2, true);

        QCOMPARE(fat_dir_index(0), -1);
        QCOMPARE(fat_dir_index(1), -1);
        QCOMPARE(fat_dir_index(2), test_dir_index1);
        QCOMPARE(fat_dir_index(3), test_dir_index2);
        QCOMPARE(fat_dir_index(4), test_dir_index1);
        QCOMPARE(fat_dir_index(5), test_dir_index1);
        QCOMPARE(fat_dir_index(6), -1);

        fat_finalize(DATA_CLUSTERS);

        QCOMPARE(fat_dir_index(0), -1);
        QCOMPARE(fat_dir_index(1), -1);
        QCOMPARE(fat_dir_index(2), test_dir_index1);
        QCOMPARE(fat_dir_index(3), test_dir_index2);
        QCOMPARE(fat_dir_index(4), test_dir_index1);
        QCOMPARE(fat_dir_index(5), test_dir_index1);
        QCOMPARE(fat_dir_index(6), -1);

        // Check the first fat page
        fat_fill(fatpage, 0, 1024);
        QCOMPARE(fatpage[0], (uint32_t) 0x0ffffff8); // media byte marker
        QCOMPARE(fatpage[1], (uint32_t) 0x0fffffff); // end of chain marker
        QCOMPARE(fatpage[2], (uint32_t) 4); // next cluster of dir 1
        QCOMPARE(fatpage[3], (uint32_t) 0x0fffffff); // end of chain marker
        QCOMPARE(fatpage[4], (uint32_t) 5); // next cluster of dir 1
        QCOMPARE(fatpage[5], (uint32_t) 0x0fffffff); // end of chain marker
        VERIFY_ARRAY(fatpage, 6, 1024, (uint32_t) 0); // everything else 0

        // Check that data_fill gets it right
        int ret = data_fill(datapage, 4096, 2, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        check_fill(datapage, MOCK_DIR_FILL, 4096, test_dir_index1, 0);

        ret = data_fill(datapage, 4096, 3, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        check_fill(datapage, MOCK_DIR_FILL, 4096, test_dir_index2, 0);

        ret = data_fill(datapage, 4096, 4, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        check_fill(datapage, MOCK_DIR_FILL, 4096, test_dir_index1, 4096);

        ret = data_fill(datapage, 4096, 5, 0, &filled);
        QCOMPARE(ret, 0);
        QCOMPARE(filled, (uint32_t) 4096);
        check_fill(datapage, MOCK_DIR_FILL, 4096, test_dir_index1, 2 * 4096);
    }