0

我有一个Parallel.For用于搜索某些值的语句。找到值后,会将其导出到文件中。找到这样的值很少见,所以一旦我在文件中收到足够的结果,我就会通过终止应用程序来停止代码的执行。

我想做的是在我的For循环语句中集成某种形式的监视器,它可以告诉我每秒执行了多少次搜索。

我认为这是一个非常基本的、必要的指标。有没有办法以这种方式对 Parallel.For 进行基准测试?

仅供参考,这是一个控制台应用程序,控制台还输出找到的结果。我希望向显示器写入一个接近准确的“搜索/秒”指标。我可以这样做吗?这些数字不需要是完美的,但我是,但它们应该在 5-10% 范围内准确。

编辑

好的,所以每个人总是要求提供代码示例,即使不需要。但这不是问题。我将在下面创建一个简单的应用程序,足以说明我的观点。

假设我有以下程序:

long minValue = 10000000;
string seed = "seed text";
object lockObj = new Object();

Parallel.For(1, Int32.Max, (i, ls) =>
{
  long val = DoCalcs(seed + i.ToString); //Assume that DoCalcs does some form of calculation.
  if (val < minValue)
  {
    lock (lockObj)
    {
      /* Write the value to a text file */
      Console.WriteLine("Found a smaller value ({0})!", minValue);
    }
  }
});

好的,这个应用程序很简单。即使它不能“永远”运行,但它可以有效地运行,因为它不会运行Int32.Max迭代。

如何以合理的准确度监控和输出此循环并行执行的次数。我可以添加一个全局累加器,但我的直觉是使用这种方法会降低性能。

任务并行库中是否有工具可以报告自调用开始以来发生了多少次循环执行Parallel.For,或者有没有办法定期查询所有正在执行的任务并安全地检索它们执行了多少次迭代?

4

1 回答 1

1

我发布了我自己对这个问题的答案,因为我知道这是一种方法。但是,我不确定是否有更优化的方法来执行此操作。如果您有比这种方法更好的答案,请发布它或发表评论,说明如何改进这种方法。

潜在解决方案

long minValue = 10000000;
string seed = "seed text";
object lockObj = new Object();

//Solution variables
int iter = 0;
object benchObj = new Object();
DateTime lastBenchmark = DateTime.Now;

Parallel.For(1, Int32.Max, (i, ls) =>
{
  long val = DoCalcs(seed + i.ToString); //Assume that DoCalcs does some form of calculation.
  if (val < minValue)
  {
    lock (lockObj)
    {
      /* Write the value to a text file */
      Console.WriteLine("Found a smaller value ({0})!", minValue);
    }
  }

  //My version of benchmark output
  lock(benchObj)
  {
    iter++;
    if (lastBenchmark.AddSeconds(5) < DateTime.Now)
    {
       Console.WriteLine("Executing {0:F3} kCalcs/s!", ((float)iter) / 5 / 1000);
       iter = 0;
       lastBenchmark = DateTime.Now;
    }        
  }
});

这和基准测试一样好Parallel.For还是我做错了什么?

于 2014-04-25T13:50:52.420 回答