2

私はいくつかの深層学習ニューラル ネットワークを実装しており、Matlab の既存のコードは通常、コンソールに出力されるだけで、ユーザーは進行状況を把握できます。

C++ の設計を行っており、アルゴリズムのコア部分をコンソールに出力したくない個別の関数に入れている場合、アルゴリズムを使用するユーザーにオプションを残す方法または設計原則はありますか?ある種の進行状況を表示しますか?

オプションのパラメーターを、人々がフックできる関数ポインターにすることはできますか?または、どうすればこれを行うことができますか?

void my_heavy_algorithm(int * data, int n,...);
4

4 に答える 4

3

アルゴリズムを関数のコレクションとして公開する場合、パラメータの 1 つを次のようなシグネチャを持つ関数ポインタにする方法があります。

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..
}

もちろん、上記はかなり単純化された例です。アルゴリズムが同時実行をサポートすると予想される場合は、内部ユーザー レポーターへのアクセスを同期する必要があります。アルゴリズムの基本クラスを作成し、具体的な派生実装を提供することを検討してください。

于 2013-03-08T16:23:23.240 に答える
1

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; }
}
于 2013-03-08T16:38:40.093 に答える
0

依存性注入を見てください。

IProgress インターフェイスを実装するオブジェクトを渡すことができます。NullProgress オブジェクトはスタブだけを持つことができますが、監視する必要のないオブジェクトに対しては実際には機能しません。

通常の方法は、計算負荷の高い作業を別のスレッドで実行し、それを使用してロックを介してメモリのセクションを更新することです。次に、UI スレッドはこのメモリ位置から定期的に読み取り、それに応じて画面を更新します。

于 2013-03-08T16:23:14.533 に答える
0

適切な進捗状況を報告するには、次の 3 つが必要です。

  1. 実行される総作業量の見積もり。
  2. これまでにどれだけの作業が行われたかの見積もり。
  3. 時間の源。

また、「重い数学」機能を「報告」する方法も必要です。これを行う 1 つの方法は、「関数の開始」、「これまでの進行状況」、および「関数の終了」で呼び出すある種の関数を用意することです。関数の開始では、「実行する総作業量」も設定されます。これまでの進捗状況は「今どれくらい完了したか」を報告し、「機能の終了」は「完了しました」と報告します。

C++ クラス環境では、これは次のように実行できます。

class Progress
{
    Progress() { };
    virtual void Start(int todo) = 0;
    virtual void Done(int doneSoFar) = 0;
    virtual void Finish();
};

これにより、他のクラスを派生できるインターフェイスが提供されます。

もちろん、「Done()」を配置するのに役立つペースを見つける必要があります。タイトなループ内に配置しすぎると、パフォーマンスに影響しますが、有用な進行状況を示すのに十分な頻度で実行する必要があります。それも。

于 2013-03-08T16:30:57.807 に答える