我应该以及如何在c++中创建需要计算的算法的进度报告
Should I and how do I create progress reporting in computation demanding algorithms in c++
我正在实现一些深度学习神经网络,现有的Matlab代码通常只是打印到控制台,这样用户就有了一个进度的想法。
当我为c++做设计时,我把算法的核心部分放在单独的函数中,我不想把东西打印到控制台,有没有办法或设计原则给使用算法的用户留下一个选项来获得某种进度指示?
可以让一个可选参数是一个函数指针,人们可以钩到,或者我该怎么做?
void my_heavy_algorithm(int * data, int n,...);
如果你要将你的算法作为一个函数集合,那么你应该让其中一个参数是一个函数指针,并带有这样的签名:
void (*reportProgress)(void*, int)
但是如果你在c++中设计你的算法,你可能应该利用封装并为你的算法创建一个类(或一组类)。在这种情况下,您不希望将函数指针作为参数添加到单个函数中。
而可以使函数指针成为类的成员。并有访问器方法来获取/设置它。或者更好的是,提供一个抽象类来报告进度。
class ProgressReporter
{
public:
virtual ~ProgressReporter() = 0;
virtual void notifyProgressChanged(void* source, int progressValue) = 0;
}
class Algo
{
private:
ProgressReporter* _userProvidedReporter = NULL;
public:
void set_ProgressReporter(ProgressReporter*); // set accessor
ProgressReporter* get_ProgressReporter(); // get accessor
void my_heavy_algorithm(int*, int, ...); // your algo. implementation fn.
}
void Algo::set_ProgressReporter(ProgressReporter* reporter){
_userProvidedReporter = reporter;
}
ProgressReporter* Algo::get_ProgressReporter(){
return _userProvidedReporter;
}
void Algo::my_heavy_algorithm(int * data, int n,...){
// do stuff
if(_userProvidedReporter != NULL)
_userProvidedReporter->notifyProgressChanged((void*)this, currentProgress);
// do more stuff
if(_userProvidedReporter != NULL)
_userProvidedReporter->notifyProgressChanged((void*)this, currentProgress);
// so on and so forth..
}
当然,上面是一个非常简单的例子。如果你希望你的算法支持并发,你应该同步访问内部用户报告器,你可以考虑为你的算法创建一个基类,并提供具体的派生实现。
STL样式函函数可能会对您有所帮助。这也允许你的算法在没有任何进度指示器的情况下使用。
例如,假设您想给出一个进度百分比指示器。
// disclaimer - I didn't compile this code
class NoProgressFeedback; // see below
void my_heavy_algorithm(int * data, int n, ProgressFeedback giveFeedback = NoProgressFeedback() {
int percentProgress = 0;
giveFeedback(percentProgress);
/* start calculations, do stuff */
percentProgress++;
giveFeedback(percentProgress);
/* continue over and repeat percentProgress updates and giveFeedback calls */
}
/* NoProgressFeedback will do no progress feedback */
class NoProgressFeedback {
public:
operator()(int percent) {}
}
如果用户代码需要反馈,那么它应该向my_heavy_algorithm函数传递一个不同的进度指示器,它应该像这样:
class GetProgressFeedback {
public:
void operator()(int percent) { std::cout << "percent advance: " << percent; }
}
看看依赖注入。
可以传递一个实现IProgress接口的对象。NullProgress对象可能只有存根,但对于您不感兴趣监视的对象不起实际作用。
通常的方法是在单独的线程中运行计算繁重的工作,并使用它通过锁来更新内存的一部分。UI线程然后定期从这个内存位置读取,并相应地更新屏幕。要报告正确的进度,您需要三件事:
- 对需要完成的全部工作的估计。
- 对到目前为止已经完成的工作的估计。
- 时间源。
你还需要一些方法让你的"重数学"函数"报告"。一种方法是在"函数的开始","到目前为止的进度"answers"函数的结束"中调用某种函数。函数的开始也设置了"要做的总工作量"。到目前为止的进度报告了"现在完成了多少",而"功能结束"表示"我完成了"。
在c++类环境中,可以这样做:
class Progress
{
Progress() { };
virtual void Start(int todo) = 0;
virtual void Done(int doneSoFar) = 0;
virtual void Finish();
};
这提供了一个接口,其他类可以从该接口派生。
当然,你仍然需要找到一个有用的速度来放置你的"Done()"-如果你把它放在一个紧密的循环中太深,它会影响性能,但你需要经常这样做,这样它也会显示一些有用的进步。
- 如何实现高效的算法来计算大型数据集的多个不同值?
- OpenCV - Python 断言错误:SAD 算法 - 立体相机视差图计算
- 通过指针算法计算数组长度
- 计算数组重复次数的组合的有效算法,加起来达到给定的总和
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 当比特数不是8的倍数时,使用切片8算法计算CRC
- 使用 Prim 算法计算最小生成树:如何使其简单?
- 计算数组中存在其总和的对数的算法
- 如何计算摘要/将使用哪种算法?
- 如何在不导致堆栈溢出的情况下计算非常大的数字和很小的 HCF.我正在使用欧几里得算法
- 如何通过 stl 容器和算法库计算两个向量的内积?
- 使用加法链接计算 (a^x)mod n.C++算法
- 通过分而治算法计算数组的最大数量
- 浮点计算可以用于任何可靠的函数,特别是容器和算法吗?
- OPENCV:如何使用5点算法从来自不同相机的两个图像之间的特征匹配来计算必需矩阵
- MFC 用于计算控件的高光、阴影等的算法或函数是什么?
- 使用位移算法计算平方根始终输出相同的数字
- 线程:如何在C或C++中精确计算算法的执行时间(函数的持续时间)
- 尝试计算算法的运行时间
- 通过计算步骤来计算算法复杂度