Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiling based refactoring in heat balance functions #8949

Merged
merged 30 commits into from
Sep 8, 2021

Conversation

xuanluo113
Copy link
Contributor

@xuanluo113 xuanluo113 commented Aug 6, 2021

Pull request overview

  • Refactoring of SetWindSpeedAt, SetSurfacetempAt at surface level.
  • Refactoring of ReportSurfaceHeatBalance and CalcThermalResilience.
  • Refactoring of the CTF term loop inInitSurfaceHeatBalance
  • Refactoring of updating some meter values updates in Outputprocessor.
  • Diffs expected for SurfaceZonePropTest_LocalEnv (see Profiling based refactoring in heat balance functions #8949 (comment)).
  • Performance improvement 1.24% as of e546b37

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

@xuanluo113 xuanluo113 self-assigned this Aug 6, 2021
@xuanluo113 xuanluo113 added the Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus label Aug 6, 2021
@xuanluo113 xuanluo113 added this to the EnergyPlus 9.6 Release milestone Aug 6, 2021
@xuanluo113 xuanluo113 marked this pull request as ready for review August 27, 2021 16:23
@xuanluo113
Copy link
Contributor Author

@nealkruis @mjwitte @JasonGlazer I'll stop making more changes to this branch and mark it ready for review, in case it continues to stepping on other branches. Still waiting for the CI, but previous (washed out) CI results were normal. Wonder if you can help to review this. The main changes are explained in the PR overview. Thanks!

@@ -661,8 +588,28 @@ void SurfaceData::set_representative_surface(EnergyPlusData &state, const int Su

void SetSurfaceOutBulbTempAt(EnergyPlusData &state)
{
for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) {
SetOutBulbTempAt(state, SurfNum);
if (state.dataEnvrn->SiteTempGradient == 0.0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these needed for all surfaces or just exterior surfaces? Does it make sense to create a vector of all exterior surfaces and just iterate over that?

Copy link
Contributor Author

@xuanluo113 xuanluo113 Sep 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried applying the calculation to exterior surfaces only and it creates diffs for some test files with natural ventilation.

For example, DoorInSurface_3 in this case uses outdoor air temperatures for ventilation calculation.

Screen Shot 2021-08-31 at 6 42 45 PM

// Calculate Heat Index and Humidex.
// The heat index equation set is fit to Fahrenheit units, so the zone air temperature values are first convert to F,
// then heat index is calculated and converted back to C.
if (state.dataHeatBalSurfMgr->reportVarHeatIndex || state.dataOutRptTab->displayThermalResilienceSummary) {
// Constance for heat index regression equation of Rothfusz.
Real64 const c1 = -42.379;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it actually makes a difference given the scope, but can probably make these constexpr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. Done.

}
for (int Meter = 1; Meter <= op->NumEnergyMeters; ++Meter) {
op->MeterValue(Meter) = 0.0; // Ready for next update
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!!

@mjwitte
Copy link
Contributor

mjwitte commented Aug 28, 2021

@xuanluo113 There are big diffs in SurfaceZonePropTest_LocalEnv that need fixing or explanation.

Copy link
Contributor

@JasonGlazer JasonGlazer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the updated functions, have you looked at how often consecutive calls use the same argument values? If this happens fairly often, it might make sense to store the previous call argument values and result and check if the new call uses the same argument values.

@amirroth
Copy link
Collaborator

amirroth commented Sep 1, 2021

@JasonGlazer Are you talking about the SetWindSpeedAt, SetSurfacetempAt functions? Yes, identifying consecutive calls with the same arguments could be an easier cache, but since zones and surfaces are note sorted in height order, the miss rate could be high. I thought Neal's team is working on reducing convective coefficient calculations by grouping surfaces (@amirroth is it true?), and the techniques would be able to apply here.

The Neal reference doesn't ring a bell. I still think the way to do this is to create a vector of vectors of surface indices where each list contains surfaces of "roughly" the same height, then calculate wind speed once for each interior list and assign to all surfaces within that list. What percentage of runtime does this part of the code take right now? Trying to determine if that is worth doing ...

@xuanluo113
Copy link
Contributor Author

@JasonGlazer Are you talking about the SetWindSpeedAt, SetSurfacetempAt functions? Yes, identifying consecutive calls with the same arguments could be an easier cache, but since zones and surfaces are note sorted in height order, the miss rate could be high. I thought Neal's team is working on reducing convective coefficient calculations by grouping surfaces (@amirroth is it true?), and the techniques would be able to apply here.

The Neal reference doesn't ring a bell. I still think the way to do this is to create a vector of vectors of surface indices where each list contains surfaces of "roughly" the same height, then calculate wind speed once for each interior list and assign to all surfaces within that list. What percentage of runtime does this part of the code take right now? Trying to determine if that is worth doing ...

@amirroth I don't remember where I got that idea then. It may not be worth it for the surface outdoor condition calculation (run time 0.5% for SetWindSpeedAt in a RefMediumOffice annual run).

@amirroth
Copy link
Collaborator

amirroth commented Sep 1, 2021

@amirroth I don't remember where I got that idea then. It may not be worth it for the surface outdoor condition calculation (run time 0.5% for SetWindSpeedAt in a RefMediumOffice annual run).

Yeah, that's borderline. There's probably more impactful things for us to look us. Put a pin in this for now.

@JasonGlazer
Copy link
Contributor

@xuanluo0113 it might be worth just testing for the the same value on consecutive calls. A lot of models get defined floor by floor so it might end up being common that the height is the same for consecutive surfaces. I'm not sure but it might be worth checking.

@mjwitte
Copy link
Contributor

mjwitte commented Sep 1, 2021

@xuanluo0113 Now there are eso diffs in 3 files: ConvectionAdaptiveSmallOffice, SurfaceZonePropTest_LocalEnv, ZoneCoupledKivaConvectionAdaptiveSmallOffice. This branch is behind develop, but these results are from 12 hours ago, and nothing was merged between your commit and 12 hrs ago (I think).

@xuanluo113
Copy link
Contributor Author

@xuanluo0113 Now there are eso diffs in 3 files: ConvectionAdaptiveSmallOffice, SurfaceZonePropTest_LocalEnv, ZoneCoupledKivaConvectionAdaptiveSmallOffice. This branch is behind develop, but these results are from 12 hours ago, and nothing was merged between your commit and 12 hrs ago (I think).

That's odd. Testing locally the diff does not reproduce. I think the diff is caused by the change to convective coefficient calculations of the other PR, which was, by the last commit, not merged into this PR.

@mitchute
Copy link
Collaborator

mitchute commented Sep 1, 2021

The convection diffs are likely due to #9035 if you haven't updated recently.

@mjwitte
Copy link
Contributor

mjwitte commented Sep 1, 2021

Well, that's what I thought, but #9035 was merged at 9:38am CDT and the CI results claim to be from 5:23am. I hate to trigger another round of CI, but I need to know.
@xuanluo0113 Please update this branch one more time.

@xuanluo113
Copy link
Contributor Author

Well, that's what I thought, but #9035 was merged at 9:38am CDT and the CI results claim to be from 5:23am. I hate to trigger another round of CI, but I need to know.
@xuanluo0113 Please update this branch one more time.

@mitchute Thanks for confirming, Matt.
@mjwitte I'll push the merge commit when finishing a few updates addressing Jason's latest comment.

@xuanluo113
Copy link
Contributor Author

@xuanluo0113 it might be worth just testing for the the same value on consecutive calls. A lot of models get defined floor by floor so it might end up being common that the height is the same for consecutive surfaces. I'm not sure but it might be worth checking.

@JasonGlazer I tested the methods of skipping consecutive calls with the same surface centroid z in the loop. See the commented-out code at the latest commit. I used a highrise-apartment building to test, and although the condition checks were able to filter out 90% of the std::pow calculations, the run time saving was not quite significant (~5%). This may be due to the extra assignment and condition checks in the loop. And if tested using a smaller model with fewer surfaces per floor, the run time may go up. So I was thinking it may not be worth it then. Please take a look if I captured what you suggested in the latest test code.

@JasonGlazer
Copy link
Contributor

@xuanluo0113 thanks for trying out saving the last value. I'm surprised it wasn't much faster but it is more assignments.

@JasonGlazer
Copy link
Contributor

It is weird that you are having an issue with two of the files in the CI that I am also having issues with: ConvectionAdaptiveSmallOffice, ZoneCoupledKivaConvectionAdaptiveSmallOffice on #9024. I have also merged develop recently and am still having the same issue but only on the Linux and MacOS tests not on Windows. Please let me know if you or @mjwitte see what is causing this.

@mjwitte
Copy link
Contributor

mjwitte commented Sep 2, 2021

This is the eso diff summary for ConvectionAdaptiveSmallOffice.

"Max absolute diff: 985080.0, field: ATTIC_ROOF_SOUTH:Surface Outside Face Convection Classification Index [](TimeStep), time:  01/21  00:10:00, relative: 999"

"Max relative diff: 999, field: ATTIC_ROOF_SOUTH:Surface Outside Face Convection Classification Index [](TimeStep), time:  01/21  00:10:00, absolute: 985080.0"

The possible values are:

enum class OutConvClass
{
    Invalid = -1,
    WindwardVertWall = 101,
    LeewardVertWall = 102,
    RoofStable = 103,
    RoofUnstable = 104,
};

An absolute diff of 985080.0 in the first timestep of the winter day says this variable isn't getting initialized.

@amirroth
Copy link
Collaborator

amirroth commented Sep 2, 2021

@xuanluo0113 it might be worth just testing for the the same value on consecutive calls. A lot of models get defined floor by floor so it might end up being common that the height is the same for consecutive surfaces. I'm not sure but it might be worth checking.

@JasonGlazer I tested the methods of skipping consecutive calls with the same surface centroid z in the loop. See the commented-out code at the latest commit. I used a highrise-apartment building to test, and although the condition checks were able to filter out 90% of the std::pow calculations, the run time saving was not quite significant (~5%). This may be due to the extra assignment and condition checks in the loop. And if tested using a smaller model with fewer surfaces per floor, the run time may go up. So I was thinking it may not be worth it then. Please take a look if I captured what you suggested in the latest test code.

Right. So the key to effective caching (which is essentially what this is) is for cache lookup and update to be significantly faster than the uncached calculation. std::pow is not as fast as cache lookup, but it's not slower by a factor of two (in fact by your calculations, according to your numbers cache lookup/update is 15% faster than just doing std::pow). The underlying math here is much worse than it is for the longer psychrometric functions.

Creating lists of (exterior) surfaces that have roughly the same centroid will not have this problem because you will not incur the overhead of the matching checks. But it may still not be worth pursuing given the overall contribution of this piece of code to runtime. Your call.

@amirroth
Copy link
Collaborator

amirroth commented Sep 2, 2021

This is the eso diff summary for ConvectionAdaptiveSmallOffice.

"Max absolute diff: 985080.0, field: ATTIC_ROOF_SOUTH:Surface Outside Face Convection Classification Index [](TimeStep), time:  01/21  00:10:00, relative: 999"

"Max relative diff: 999, field: ATTIC_ROOF_SOUTH:Surface Outside Face Convection Classification Index [](TimeStep), time:  01/21  00:10:00, absolute: 985080.0"

An absolute diff of 985080.0 in the first timestep of the winter day says this variable isn't getting initialized.

999 is a valid absolute relative diff? That also seems strange.

@mjwitte
Copy link
Contributor

mjwitte commented Sep 2, 2021

999 is a valid absolute relative diff?

That's a divide by zero indicator. MathDiff might even have logic to write that explicitly if the base value is zero.

@xuanluo113
Copy link
Contributor Author

I just deleted the commented-out code for testing the caching.

And if the CI turns green this time, this is ready for another review.

Further investigations of caching and naming conventions of the reportable Q variable will go to the next PR.

@xuanluo113 xuanluo113 mentioned this pull request Sep 3, 2021
20 tasks
@mjwitte
Copy link
Contributor

mjwitte commented Sep 8, 2021

CI is happy here, merging.

@mjwitte mjwitte merged commit 4d70f44 into NREL:develop Sep 8, 2021
@mjwitte mjwitte deleted the surf-wind-speed branch September 8, 2021 16:34
@xuanluo113
Copy link
Contributor Author

CI is happy here, merging.

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Performance Includes code changes that are directed at improving the runtime performance of EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants