HPCE / hpce-2017-cw5

1 stars 6 forks source link

Development: use a dev branch or v1..v2..v3 ? #11

Closed natoucs closed 6 years ago

natoucs commented 6 years ago
  1. When optimising a puzzle, is it better to create v1, v2, v3 etc in the same directory like in CW3 or is it better to keep one version of the puzzle in the directory (provider) and use git to submit different versions ('dev branch') on top of each other ?

  2. To use a dev branch, what is the procedure ?

  3. To use v1,v2,v3, where should the existence of the new cpp files be added ? I can't find a file in 'provider' where the different files/function can be listed (like the factory in cw3).

m8pple commented 6 years ago

I'm not sure there is a clear answer to single-branch/multiple-files versus multiple-branches/single-file. General wisdom would probably suggest multiple branches, but that can make it quite difficult to run ad-hoc performance comparisons.

Often I will keep around key milestone implementations in the same directory, so that I give myself the option of switching implementations without recompiling. However, these should represent only the endpoints of a particular performance optimisation approach, and should be believed to be completely correct. In this coursework you can only expose one version of your code via the API, so you can give yourself some kind of run-time switch to select between them - for example an environment variable that let's you select an implementation, but by default (if it is not set) selects the highest-performing last-known-good implementation.

However, you should avoid the temptation to keep broken versions around. They will only confuse you.

Another reason for sometimes keeping around older versions in the same code-base is that you may want to dynamically dispatch to a specific implementation. For example, once you have a GPU solution you may want to look at the performance across a spectrum compared to a TBB implementation - is the GPU version always the one you want, or should you deferr that decision till run-time when you know the scale?

In terms of how you expose multiple implementations (if you have them), you do own the puzzle factory (void puzzler::PuzzleRegistrar::UserRegisterPuzzles()), so at run-time you can choose to register one of multiple potential puzzles that solve the same problem.

You can also create a dynamic dispatch class, so something like:

class WibbleProvider
  : WibblePuzzle
{
public:
  WibbleProvider()
  {
     m_prov1=std::make_shared<WibbleProviderV1>();
     m_prov2=std::make_shared<WibbleProviderV2>();
  }

  void Execute( ... )
   {
      if(something){
         m_prov1->Execute(...);
      }else{
         m_prov2->Execute(...);
      }
   }
};

I'm pretty sure there is a design pattern name for this, but it escapes me right now.

Regarding branches, I'm afraid I'll deferr to the book, as it is better explained with diagrams. Plus there are endless arguments about the "correct" branching model.

natoucs commented 6 years ago

thank you for the detailed explanation!