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

Performance Issue for Single Thread on LinearObjectPool #5

Open
dave-fl opened this issue Feb 24, 2024 · 4 comments
Open

Performance Issue for Single Thread on LinearObjectPool #5

dave-fl opened this issue Feb 24, 2024 · 4 comments

Comments

@dave-fl
Copy link

dave-fl commented Feb 24, 2024

Based on the docs this doesn't look right. I am getting much slower numbers with LinearObjectPool.

Edit:

After looking at the code, I can see that the pages are a linked list so as pages become occupied the time required to find a new page increases. I suppose this is to be expected.

     Running benches\my_benchmarks.rs (target\release\deps\my_benchmarks-1aeba3f202e206f0.exe)
Gnuplot not found, using plotters backend
using pool              time:   [1.6677 ms 1.6886 ms 1.7122 ms]
                        change: [+0.2426% +1.6519% +3.1663%] (p = 0.02 < 0.05)
                        Change within noise threshold.
Found 12 outliers among 100 measurements (12.00%)
  1 (1.00%) high mild
  11 (11.00%) high severe

no pool                 time:   [13.575 µs 13.926 µs 14.290 µs]
                        change: [-5.0569% +3.7812% +11.991%] (p = 0.46 > 0.05)
                        No change in performance detected.
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe

using other pool        time:   [242.83 µs 245.38 µs 248.24 µs]
                        change: [+4.1452% +6.1576% +8.3049%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) high mild
  1 (1.00%) high severe

Here is the test:

const VEC_SIZE: usize = 16384;
const BATCH_SIZE: usize = 8192;
struct Test {
    id: u64
}

impl Default for Test {
    fn default() -> Self {
        Self {id: 0}
    }
}

fn using_pool(c: &mut Criterion) {
    c.bench_function("using pool", |b| {
        b.iter_batched(
            || {
                let pool = lockfree_object_pool::LinearObjectPool::<Test>::new(|| Default::default(), |_v| {});
                let v: Vec<_> = (0..VEC_SIZE).map(|_| pool.pull()).collect();
                drop(v);
                (pool, Vec::with_capacity(VEC_SIZE))

            },
            |(pool, mut vec)| {
                for index in 0..BATCH_SIZE {
                    vec.insert(index, black_box(pool.pull()));
                }
            },
            BatchSize::SmallInput
        );
    });
}

fn no_pool(c: &mut Criterion) {
    c.bench_function("no pool", |b| {
        b.iter_batched(
            || {
                Vec::with_capacity(VEC_SIZE)

            },
            |mut vec| {
                for index in 0..BATCH_SIZE {
                    vec.insert(index, black_box(Test{id: 0}));
                }
            },
            BatchSize::SmallInput
        );
    });
}

fn using_other_pool(c: &mut Criterion) {
    c.bench_function("using other pool", |b| {
        b.iter_batched(
            || {
                let pool: Pool<Test> = Pool::new(VEC_SIZE, || Test{id: 0});
                (pool, Vec::<Reusable<Test>>::with_capacity(VEC_SIZE))

            },
            |(pool, mut vec)| {
                for index in 0..BATCH_SIZE {
                    let t = pool.try_pull().unwrap();
                    vec.insert(index, black_box(t));
                }
            },
            BatchSize::SmallInput
        );
    });
}

criterion_group!(benches, using_pool, no_pool,using_other_pool);
criterion_main!(benches);
@EVaillant
Copy link
Owner

Maybe :

  • size of (Test) 8 vs 16k
  • linux vs windows
  • my tests were done 3 years ago

which pool do you use

 Pool<Test>

?

@dave-fl
Copy link
Author

dave-fl commented Feb 26, 2024

crate 'object-pool'

When using SpinLockObjectPool things are similar. This is really a function of that page taking O(N) to find. If it was being pulled from a last known free page or tail, things would be different.

@EVaillant
Copy link
Owner

I add a bench with your test case https://evaillant.github.io/lockfree-object-pool/benches/criterion/reuse/report/index.html
I think you're right.

@taikulawo
Copy link

Same here, metrics-tracing-context use lockfree-object-pool to create Lables. It seems there are huge contention in

perf top show many time waste on CPU nop.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants