[PATCH] Stop doing the (very expensive) pow() calculation pointlessly

Anton Lundin glance at acc.umu.se
Wed Jan 29 04:38:59 UTC 2014

On 22 January, 2014 - Linus Torvalds wrote:

> On Wed, Jan 22, 2014 at 8:25 AM, Dirk Hohndel <dirk at hohndel.org> wrote:
> >
> > What I think would be the right thing to do is similar to what I think
> > most dive computers do as well:
> >
> > Calculate a constant rate ascent until we would actually cross above the
> > ceiling (so not, "ascend from where we are NOW to the ceiling for NOW",
> > but instead "ascend until by going up another 3m/10ft we would violate
> > the then current ceiling"). Then wait in increments of full minutes
> > until we can ascend to the next 3m/10ft potential stop (using the same
> > logic as above).
> That is very close to what we do now, with the addition of the
> 1-minute stop granularity (which is what my one-liner patch did).
> But your "go up another 3m" is ambiguous. Do you mean "go up 3m from
> where we are now" (which is *not* what the code does now) or do you
> mean "go up to the next 3m boundary" (which is pretty much exactly
> what the code does now.
> So if you mean "go up to the next 3m boundary, but then stop for whole
> minutes", then that is literally exactly what changing time_stepsize
> from 10 to 60 would do.
> Side note: adding Anton explicitly to the Cc, to see if he has
> comments and might not have noticed the mailing list thread. He's the
> original author of the code in question. Anton - mind checking my
> commentary on the TTS algorithm in my previous mail in the thread? I
> might have missed something..

Chokay. Now in the window between getting married and eaten by lions, i
finally got time to do a proper read through of this thread.

The first explanations of the DECO STOP / TTS / NDL algorithm i wrote
had some minor inaccuracies, but the last recap here is quite accurate.

I tried to mimic what i think most deco software and computers i used
does. The main thing here to remember is that all of it are just made up
math, trying to keep you alive, and i tried to calculate TTS based on
how I dive.
The idea about just following the ceiling is what some computers do too
per example some Suunto computers and AP Inspiration.
There are no "right" or "wrong" here, just different ways of viewing
decompression. Decompression is part art, part science, part made up =)

The code currently starts out by a 12 m/min accent speed until you hit
your actual ceiling rounded up (deeper) to the first deco stop. That
ceiling can change from when you start your accent until you hit your
actual ceiling. This is currently done in 1s steps.
(ascent_s_per_step / ascent_mm_per_step)

Then it calculates how long to stay at that stop, as said in 10s steps.
10s is arbitrary chosen because it was larger than 1s, which made
everything to slow  and gave me TTS-values that looked about right,
based on my diving profiles from dives I done based on profiles
calculated in other software like V-planner and Decoplanner.

Then we move to the next stop at 1 m/min (ascent_s_per_deco_step /

Above all of these values there are a big :
/* FIXME: This should be configurable */ 

I have on my todo-list to build some preferences panel about that and
hook those up in the planner to.

One fun "feature" of the TTS code is that it doesn't calculate TTS with
gas switches, it continues with whatever gas your on right now. I thought
tis was a quite handy thing because you can see quite clearly now your
deco plan was affected by the gas switch. In one if my dives we dropped
from 269 minutes TTS to 167 minutes TTS when we switched to the fist deep
deco gas, then again from 131 to 56 on the next gas switch.

Now to the patches Linus posted. I'm totally fine with a 1-16 min diff in
the TTS for a x6 speedup of that inner loop. Based on my experiments its
usually about 1-4 minutes. Maybe we should make it configurable?

About the removal of the interpolate in calculate_deco_information,
thats actually Linus code to begin with. Git just blames me because i
broke up the huge calculate_deco_information to multiple functions.
As you said earlier, we would need to copy more things from the previous
sample than just ceiling.
But, the problem with removing the interpolate there, is that if you
have a dive with a bit longer between the samples, that would e quite
wrong. This might be artificial, but its present in our hand-crafted
test dives.
We could instead add a lager step value than 1 s there, something that
the POC-patch i attached suggests.

I'm heading off on vacation tomorrow, so it might take a while before i
resurface on the mailinglist again.


Anton Lundin	+46702-161604
-------------- next part --------------
diff --git i/profile.c w/profile.c
index 82aa274..5174832 100644
--- i/profile.c
+++ w/profile.c
@@ -1159,11 +1159,16 @@ static void calculate_deco_information(struct dive *dive, struct divecomputer *d
 	for (i = 1; i < pi->nr; i++) {
 		struct plot_data *entry = pi->entry + i;
 		int j, t0 = (entry - 1)->sec, t1 = entry->sec;
-		for (j = t0+1; j <= t1; j++) {
+		int time_stepsize = 20;
+		if (t0 != t1 && t1 - t0 < time_stepsize)
+			time_stepsize = t1 - t0;
+		for (j = t0 + time_stepsize; j <= t1; j += time_stepsize) {
 			int depth = interpolate(entry[-1].depth, entry[0].depth, j - t0, t1 - t0);
 			double min_pressure = add_segment(depth_to_mbar(depth, dive) / 1000.0,
-					&dive->cylinder[entry->cylinderindex].gasmix, 1, entry->po2 * 1000, dive);
+					&dive->cylinder[entry->cylinderindex].gasmix, time_stepsize, entry->po2 * 1000, dive);
 			tissue_tolerance = min_pressure;
+			if (j - t0 < time_stepsize)
+				time_stepsize = j - t0;
 		if (t0 == t1)
 			entry->ceiling = (entry - 1)->ceiling;

More information about the subsurface mailing list