Since the code is heavy on loops, reducing the number of "if" statements will provide a nice speed boost. For example, from "lisInfiltration.cpp" you have these lines of code (applies to other files as well)
if (SwitchBuffers && !SwitchSedtrap)
if(BufferID->Drc > 0 && BufferVol->Drc > 0)
WH->Drc = 0;
if (SwitchBuffers && !SwitchSedtrap)
if(BufferID->Drc > 0 && BufferVol->Drc > 0)
WH->Drc = 0;
To copy to clipboard, switch view to plain text mode
Because of the && operator, lines 1 and 2 account for 4 if statements. Using the logical & operator can reduce this to 2 if statements without changing the structure of the code.
if (SwitchBuffers & !SwitchSedtrap)
if(BufferID->Drc > 0 & BufferVol->Drc > 0)
WH->Drc = 0;
if (SwitchBuffers & !SwitchSedtrap)
if(BufferID->Drc > 0 & BufferVol->Drc > 0)
WH->Drc = 0;
To copy to clipboard, switch view to plain text mode
This could further be reduced to a single if statement ...
if(SwitchBuffers & !SwitchSedtrap & BufferID->Drc > 0 & BufferVol->Drc > 0)
if(SwitchBuffers & !SwitchSedtrap & BufferID->Drc > 0 & BufferVol->Drc > 0)
To copy to clipboard, switch view to plain text mode
But careful observation and profiling need to be done to make sure it doesn't adversely effect the speed and run slower than the original if statement. The reason is that accessing memory outside of the L1 and L2 cache is slow. If BufferID is outside of those caches then it will be brought into the cache unnecessarily if(SwitchBuffers & !SwitchSedtrap) is false.
The second example would be my preferred choice.
Next, to help the compiler you should define constant variables as const. This will tell the compiler that the variable is not suppose to change and the compiler can apply some optimizations. For example, this
for(...) {
double Perim, Radius, Area, beta = 0.6;
double _23 = 2.0/3.0;
double beta1 = 1/beta;
double wh = ChannelWH->Drc;
double FW = ChannelWidth->Drc;
double grad = sqrt(ChannelGrad->Drc);
double dw = 0.5*(ChannelWidthUpDX->Drc - FW); // extra width when non-rectamgular
}
for(...) {
double Perim, Radius, Area, beta = 0.6;
double _23 = 2.0/3.0;
double beta1 = 1/beta;
double wh = ChannelWH->Drc;
double FW = ChannelWidth->Drc;
double grad = sqrt(ChannelGrad->Drc);
double dw = 0.5*(ChannelWidthUpDX->Drc - FW); // extra width when non-rectamgular
}
To copy to clipboard, switch view to plain text mode
... can be changed to this.
for(...) {
double Perim, Radius, Area;
const double beta = 0.6;
const double _23 = 2.0/3.0;
const double beta1 = 1/beta;
double wh = ChannelWH->Drc;
double FW = ChannelWidth->Drc;
double grad = sqrt(ChannelGrad->Drc);
double dw = 0.5*(ChannelWidthUpDX->Drc - FW); // extra width when non-rectamgular
}
for(...) {
double Perim, Radius, Area;
const double beta = 0.6;
const double _23 = 2.0/3.0;
const double beta1 = 1/beta;
double wh = ChannelWH->Drc;
double FW = ChannelWidth->Drc;
double grad = sqrt(ChannelGrad->Drc);
double dw = 0.5*(ChannelWidthUpDX->Drc - FW); // extra width when non-rectamgular
}
To copy to clipboard, switch view to plain text mode
again, not really changing the code structure of what you've already got, just making your intent clear and helping the compiler along the way.
And finally, this will change the code structure, but eliminates an extra if statement when certain conditions are met. Change this ...
if (Perim > 0)
Radius = Area/Perim;
else
Radius = 0;
ChannelAlpha->Drc = pow(ChannelN->Drc/grad * powl(Perim, _23),beta);
if (ChannelAlpha->Drc > 0)
ChannelQ->Drc = pow(Area/ChannelAlpha->Drc, beta1);
else
ChannelQ->Drc = 0;
if (Perim > 0)
Radius = Area/Perim;
else
Radius = 0;
ChannelAlpha->Drc = pow(ChannelN->Drc/grad * powl(Perim, _23),beta);
if (ChannelAlpha->Drc > 0)
ChannelQ->Drc = pow(Area/ChannelAlpha->Drc, beta1);
else
ChannelQ->Drc = 0;
To copy to clipboard, switch view to plain text mode
to this ... (preloading)
Radius = 0;
if (Perim > 0)
Radius = Area/Perim;
ChannelAlpha->Drc = pow(ChannelN->Drc/grad * powl(Perim, _23),beta);
ChyannelQ->Drc = 0;
if (ChannelAlpha->Drc > 0)
ChannelQ->Drc = pow(Area/ChannelAlpha->Drc, beta1);
Radius = 0;
if (Perim > 0)
Radius = Area/Perim;
ChannelAlpha->Drc = pow(ChannelN->Drc/grad * powl(Perim, _23),beta);
ChyannelQ->Drc = 0;
if (ChannelAlpha->Drc > 0)
ChannelQ->Drc = pow(Area/ChannelAlpha->Drc, beta1);
To copy to clipboard, switch view to plain text mode
Here the variables are preloaded with one of the 2 if conditions. You either want to preload with the most likely to occur, or the least expensive to preload. Here preloading with 0 is the least expensive (xor var, var) even if ChannelAplpha->Drc is most likely to occur.
HTH
Bookmarks