我有一个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
开始以来发生了多少循环执行,或者是否有办法定期查询所有正在执行的任务并安全地检索他们执行了多次迭代?
答案 0 :(得分: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
一样好吗,或者我做错了什么?