Skip to content

Commit

Permalink
Only perform a single sort when in local_spikevec_sort (#2453)
Browse files Browse the repository at this point in the history
* Only perform a single sort when in local_spikevec_sort

On a benchmark of 10000 (gid, time) pairs, with time varying from 0 to 10s,
and gids from 0-9, I get roughly half the time:
------------------------------------------------------
Benchmark            Time             CPU   Iterations
------------------------------------------------------
dual_sort        0.909 ms        0.909 ms          758
single_sort      0.546 ms        0.546 ms         1285

* fix the logic

* fix comment

* Use non-stable sort for local_spikevec_sort

* confirmed that:
   nrnhines: "Since there are no equivalent (spiketime, gid) elements (and if there were, the order would not matter)"

for a 10000 element array of synthetic data, the runtime is:
```
Benchmark                     Time             CPU   Iterations
dual_sort                 0.921 ms        0.921 ms          751
single_sort               0.533 ms        0.533 ms         1303
single_sort_unstable      0.480 ms        0.480 ms         1461
```
  • Loading branch information
mgeplf authored Aug 17, 2023
1 parent 21f1654 commit efc28fe
Showing 1 changed file with 4 additions and 7 deletions.
11 changes: 4 additions & 7 deletions src/coreneuron/io/output_spikes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,11 @@ static void local_spikevec_sort(std::vector<double>& isvect,
// first build a permutation vector
std::vector<std::size_t> perm(isvect.size());
std::iota(perm.begin(), perm.end(), 0);
// sort by gid (second predicate first)
std::stable_sort(perm.begin(), perm.end(), [&](std::size_t i, std::size_t j) {
return isvecg[i] < isvecg[j];
});
// then sort by time
std::stable_sort(perm.begin(), perm.end(), [&](std::size_t i, std::size_t j) {
return isvect[i] < isvect[j];
// sort by time then gid
std::sort(perm.begin(), perm.end(), [&](std::size_t i, std::size_t j) {
return isvect[i] < isvect[j] || (isvect[i] == isvect[j] && isvecg[i] < isvecg[j]);
});

// now apply permutation to time and gid output vectors
std::transform(perm.begin(), perm.end(), osvect.begin(), [&](std::size_t i) {
return isvect[i];
Expand Down

0 comments on commit efc28fe

Please sign in to comment.