stim: re-express the AbstractStimulus list op as a fold

this gives a big perf boost: 10.5 fps -> 446 fps.

still far lower from the 720 fps we got on an ordinary Vec<Box<dyn
AbstractRegion>>. i think we had achieved 730  using the old
ListVisitor.

it's probably not worth list-ifying the stimuli; at least not at this
level. at the least, we probably want only 5 stimuli: one per core.
if we did that, the stimuli could even have all the same typename,
and be put into a plain old array; no boxing.
This commit is contained in:
2022-08-17 03:22:45 -07:00
parent ffa13ccd79
commit ee98e1a060

View File

@@ -1,7 +1,7 @@
use crate::real::Real as _;
use crate::cross::vec::Vec3;
use crate::geom::{HasCrossSection, Meters, Region};
use coremem_cross::compound::list::{Map, MapVisitor, Sum};
use coremem_cross::compound::list::{Fold, FoldOp};
use rand;
/// field densities
@@ -45,21 +45,19 @@ struct StimulusEvaluator {
pos: Meters,
}
impl<S: AbstractStimulus> MapVisitor<&S> for StimulusEvaluator {
impl<S: AbstractStimulus> FoldOp<Fields, &S> for StimulusEvaluator {
type Output = Fields;
fn map(&self, s: &S) -> Self::Output {
s.at(self.t_sec, self.pos)
fn feed(&self, prev: Fields, next: &S) -> Self::Output {
prev + next.at(self.t_sec, self.pos)
}
}
impl<L: Sync> AbstractStimulus for L
where
for<'a> &'a L: Map<StimulusEvaluator>,
for<'a> <&'a L as Map<StimulusEvaluator>>::Output: Sum<Fields, Output=Fields>,
for<'a> &'a L: Fold<StimulusEvaluator, Fields, Output=Fields>,
{
fn at(&self, t_sec: f32, pos: Meters) -> Fields {
self.map(StimulusEvaluator { t_sec, pos })
.sum(Fields::default())
self.fold(StimulusEvaluator { t_sec, pos}, Fields::default())
}
}