Results with node functions performing prefetching and processing four
buffers at a time, with vector instructions emitted by both compilers
in the update of next node indices:
C: 1.08e1 clocks per packet
Rust: 1.09e1 clocks per packet
So again, approximately equal.
The code for this:
C:
https://github.com/rshearman/vpp/blob/48ca99dc7079bd46b2bb37605ec3d62a44bbf58f/src/plugins/example-c/example_node.c
Rust:
https://github.com/rshearman/vpp-plugin-rs/blob/de41333b46b671b8c61182b6f38d0996fce8cf5e/vpp-example-plugin/src/lib.rs
Median values from:
$ grep example */show_runtime.txt
c-1/show_runtime.txt:example-c active
809723 28203452 0 1.08e1
34.83
c-2/show_runtime.txt:example-c active
816954 28795970 0 1.06e1
35.25
c-3/show_runtime.txt:example-c active
906334 28421093 0 1.16e1
31.36
rust-1/show_runtime.txt:example active
864643 28368780 0 1.09e1
32.81
rust-2/show_runtime.txt:example active
924042 29116994 0 1.13e1
31.51
rust-3/show_runtime.txt:example active
858871 29217427 0 1.07e1
34.02
All of these runs were done while offering the highest packet rate the
traffic generator could do (rather than NDR in the previous set of
results).
Thanks,
Rob
On Tue, 25 Nov 2025 at 14:52, Robert Shearman via lists.fd.io
<[email protected]> wrote:
>
> There is SIMD usage in vlib_get_buffers (and the Rust implementation
> of the same functionality), so it does cover that base, but I can
> enhance the plugins to perform prefetching.
>
> Thanks,
> Rob
>
> On Tue, 25 Nov 2025 at 13:55, Damjan Marion via lists.fd.io
> <[email protected]> wrote:
> >
> >
> > Well, your C plugin is very basic, no prefetching, no instruction level
> > parallelism, no SIMD usage so no surprises that numbers are close.
> > Any chance you can try something involving those techniques?
> >
> > Thanks,
> >
> > Damjan
> >
> >
> > > On 24.11.2025., at 21:22, Robert Shearman via lists.fd.io
> > > <[email protected]> wrote:
> > >
> > > I've been able to capture some numbers for what I believe is a fair
> > > apples-to-apples comparison of a C plugin versus a Rust plugin, and a
> > > short summary is that they are approximately equal in performance.
> > >
> > > C: 1.22e1 clock cycles per packet
> > > Rust: 1.19e1 clock cycles per packet
> > >
> > > Details:
> > >
> > > Rust plugin code (also using vpp-plugin crate from same git hash):
> > > https://github.com/rshearman/vpp-plugin-rs/tree/15437cd8d848fd877dbb5858dec1e4ab853bbd42/vpp-example-plugin
> > > C plugin code:
> > > https://github.com/rshearman/vpp/blob/8ebcf29538b1145e376bdf7f8b405ca4822e9c24/src/plugins/example-c/example_node.c
> > >
> > > Obviously, the plugins here are about as basic as it comes but the
> > > more basic the plugins the easier it is to perform an apples-to-apples
> > > comparison and visually validate they are doing the same job.
> > >
> > > Rust compiler version:
> > > rustc 1.91.0 (f8297e351 2025-10-28)
> > >
> > > C compiler version:
> > > Ubuntu clang version 18.1.3 (1ubuntu1)
> > > Target: x86_64-pc-linux-gnu
> > > Thread model: posix
> > > InstalledDir: /usr/bin
> > >
> > > The test setup is a VM with 8G of memory where TRex is running,
> > > connected via two virtio interfaces to a second VM with 4G of memory
> > > where vpp is run. Both VMs have 2 lcores pinned to set lcores on the
> > > hypervisor. Both VMs are running Ubuntu 24.04.3, along with the
> > > hypervisor. Given that this was a one-time performance test, I made no
> > > attempt at doing CPU isolation in either the guest VMs or the
> > > hypervisor, with the hope that the noise in the results that this
> > > causes is acceptable.
> > >
> > > VPP code was built using "make pkg-deb" and then installed as packages
> > > in the VM, with the only change to the configuration being to
> > > configure `workers 1`. The Rust plugin was built using `cargo build
> > > --release` and then the resulting .so file for the vpp-example-plugin
> > > was copied into the expected location in the VM.
> > >
> > > IPv4 UDP 1500-byte packets are generated from TRex in an NDR test
> > > (although the overhead from the example plugin turned out to be lost
> > > in the noise), meaning that these packets don't match in the plugins
> > > under test so the packets aren't dropped, but follow the next-feature
> > > path.
> > >
> > > The CPU on which the test was run is 11th Gen Intel(R) Core(TM)
> > > i5-11600K @ 3.90GHz (Rocket Lake) with 12 cores (although only 4 cores
> > > were being used by the VMs part of the test topology), meaning Icelake
> > > multiarch functions are in use.
> > >
> > > Three runs were performed for each of the C and Rust plugins being
> > > enabled (with the C and Rust runs interleaved to avoid bias, such as
> > > the CPU becoming thermal-limited in performance), with the median
> > > clocks value being picked for each (to avoid bias from outliers):
> > >
> > > $ grep example */show_runtime.txt
> > > c-1/show_runtime.txt:example-c active
> > > 5567253 168564707 0 1.31e1
> > > 30.28
> > > c-2/show_runtime.txt:example-c active
> > > 5724169 169749914 0 1.22e1
> > > 29.65
> > > c-3/show_runtime.txt:example-c active
> > > 5831253 165498112 0 1.15e1
> > > 28.38
> > > rust-1/show_runtime.txt:example active
> > > 5423194 162165846 0 1.19e1
> > > 29.90
> > > rust-2/show_runtime.txt:example active
> > > 5768590 172390325 0 1.15e1
> > > 29.88
> > > rust-3/show_runtime.txt:example active
> > > 4822482 136679532 0 1.22e1
> > > 28.34
> > >
> > > The full "vppctl show runtime" output for the median runs are attached
> > > for reference.
> > >
> > > Thanks,
> > > Rob
> > >
> > > On Fri, 14 Nov 2025 at 09:34, Robert Shearman <[email protected]>
> > > wrote:
> > >>
> > >> Hi Damjan,
> > >>
> > >> I haven't done that yet, but I'll give it a go!
> > >>
> > >> Thanks,
> > >> Rob
> > >>
> > >> On Thu, 13 Nov 2025 at 12:49, Damjan Marion via lists.fd.io
> > >> <[email protected]> wrote:
> > >>>
> > >>>
> > >>> Hi,
> > >>>
> > >>> have you tried to implement something already existing in C and compare
> > >>> performance?
> > >>>
> > >>> I would really like to se apple-to-apple comparison of same
> > >>> functionality in
> > >>> C and rust when it comes to high-performance datapath code.
> > >>>
> > >>> Thanks,
> > >>>
> > >>> —
> > >>> Damjan
> > >>>
> > >>>
> > >>>> On 12.11.2025., at 13:21, Robert Shearman via lists.fd.io
> > >>>> <[email protected]> wrote:
> > >>>>
> > >>>> Hi folks,
> > >>>>
> > >>>> I believe there could be benefits in having the option of writing VPP
> > >>>> plugins in Rust, so to that end I've created a set of Rust
> > >>>> crates/packages to make it easier to write plugins, make use of the
> > >>>> underlying VPP C APIs, and an example feature plugin all of which can
> > >>>> be found here:
> > >>>>
> > >>>> https://github.com/rshearman/vpp-plugin-rs/
> > >>>>
> > >>>> The goal is to have performance parity with VPP plugins written in C
> > >>>> (compiling with support for different instruction sets similar to C
> > >>>> code is already supported, for example), but whilst still feeling like
> > >>>> Rust code.
> > >>>>
> > >>>> I'd be interested in feedback from the VPP development community.
> > >>>>
> > >>>> Thanks,
> > >>>> --
> > >>>> Rob Shearman
> > >>>>
> > >>>>
> > >>>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>
> > >>
> > >> --
> > >> Rob Shearman
> > >
> > >
> > >
> > > --
> > > Rob Shearman
> > > <rust_vppctl_show_runtime.txt><c_vppctl_show_runtime.txt>
> > >
> > >
> >
> >
> >
> >
>
>
> --
> Rob Shearman
>
>
>
--
Rob Shearman
Thread 0 vpp_main (lcore 1)
Time 261.0, 10 sec internal node vector rate 0.00 loops/sec 1883718.14
vector rates in 0.0000e0, out 1.5376e-2, drop 0.0000e0, punt 0.0000e0
Name State Calls Vectors
Suspends Clocks Vectors/Call
GigabitEthernet6/0/0-output active 2 2
0 8.48e4 1.00
GigabitEthernet6/0/0-tx active 2 2
0 1.76e4 1.00
GigabitEthernet7/0/0-output active 2 2
0 1.53e4 1.00
GigabitEthernet7/0/0-tx active 2 2
0 1.79e4 1.00
acl-plugin-fa-cleaner-process "event wait" 0 0
1 1.86e4 0.00
admin-up-down-process "event wait" 0 0
1 2.84e4 0.00
api-rx-from-ring "any wait" 0 0
19 1.07e6 0.00
avf-process "event wait" 0 0
1 1.76e4 0.00
bfd-process "event wait" 0 0
1 8.79e3 0.00
bond-process "event wait" 0 0
1 8.40e3 0.00
cnat-scanner-process "event wait" 0 0
1 1.58e4 0.00
deleted-722 "not started 1 0
0 3.46e4 0.00
dhcp-client-process "any wait" 0 0
1 9.71e3 0.00
dhcp6-client-cp-process "any wait" 0 0
1 8.16e3 0.00
dhcp6-pd-client-cp-process "any wait" 0 0
1 1.08e4 0.00
dhcp6-pd-reply-publisher-proce"event wait" 0 0
1 7.89e3 0.00
dhcp6-reply-publisher-process "event wait" 0 0
1 7.35e3 0.00
dpdk-process "any wait" 0 0
399 1.07e5 0.00
fib-walk "any wait" 0 0
131 1.09e4 0.00
flow-report-process "any wait" 0 0
1 8.63e3 0.00
flowprobe-timer-process "any wait" 0 0
1 2.59e4 0.00
igmp-timer-process "event wait" 0 0
1 2.54e4 0.00
ikev2-manager-process "event wait" 0 0
1 2.79e4 0.00
ioam-export-process "any wait" 0 0
1 1.46e4 0.00
ip-neighbor-event "event wait" 0 0
1 9.41e3 0.00
ip4-full-reassembly-expire-wal "any wait" 0 0
5214 5.20e3 0.00
ip4-neighbor-age-process "event wait" 0 0
1 8.15e3 0.00
ip4-sv-reassembly-expire-walk "any wait" 0 0
27 5.97e3 0.00
ip6-full-reassembly-expire-wal "any wait" 0 0
5214 5.58e3 0.00
ip6-mld-process "any wait" 0 0
261 5.32e3 0.00
ip6-neighbor-age-process "event wait" 0 0
1 1.49e4 0.00
ip6-ra-process "any wait" 0 0
261 5.06e3 0.00
ip6-rewrite-mcast active 2 2
0 4.93e3 1.00
ip6-rs-process "any wait" 0 0
1 7.63e3 0.00
ip6-sv-reassembly-expire-walk "any wait" 0 0
27 7.94e3 0.00
l2-arp-term-publisher "event wait" 0 0
1 8.35e4 0.00
l2fib-mac-age-scanner-process "event wait" 0 0
1 9.11e3 0.00
lldp-process "event wait" 0 0
1 6.07e6 0.00
memif-process "event wait" 0 0
1 2.98e4 0.00
nat44-ei-ha-process "event wait" 0 0
1 2.81e4 0.00
nsh-md2-ioam-export-process "any wait" 0 0
1 1.42e5 0.00
rd-cp-process "any wait" 0 0
1 1.73e4 0.00
send-dhcp6-client-message-proc "any wait" 0 0
1 1.80e4 0.00
send-dhcp6-pd-client-message-p "any wait" 0 0
1 1.66e4 0.00
sflow-process-samples "any wait" 0 0
261 7.44e3 0.00
startup-config-process "not started 1 0
1 1.71e4 0.00
statseg-collector-process "suspended" 0 0
27 2.50e6 0.00
udp-ping-process "any wait" 0 0
1 3.17e4 0.00
unix-cli-new-session "any wait" 0 0
23 3.59e3 0.00
unix-cli-process-0 "running" 9 0
23 2.66e6 0.00
vhost-user-process "any wait" 0 0
1 4.33e4 0.00
vhost-user-send-interrupt-proc "any wait" 0 0
1 2.28e4 0.00
vpe-link-state-process "event wait" 0 0
3 6.53e3 0.00
vrrp-periodic-process "event wait" 0 0
1 3.90e4 0.00
vxlan-gpe-ioam-export-process "any wait" 0 0
1 1.96e4 0.00
wg-timer-manager "event wait" 0 0
1 2.38e6 0.00
---------------
Thread 1 vpp_wk_0 (lcore 0)
Time 261.0, 10 sec internal node vector rate 23.87 loops/sec 8168412.64
vector rates in 6.5041e5, out 6.4707e5, drop 1.6097e-1, punt 1.1544e-2
Name State Calls Vectors
Suspends Clocks Vectors/Call
GigabitEthernet6/0/0-output active 5 5
0 3.44e3 1.00
GigabitEthernet6/0/0-tx active 5 5
0 1.55e4 1.00
GigabitEthernet7/0/0-output active 5724173 169749916
0 1.29e1 29.65
GigabitEthernet7/0/0-tx active 5724173 168877756
0 1.68e2 29.50
arp-input active 2 2
0 6.54e3 1.00
arp-reply active 2 2
0 6.45e4 1.00
dpdk-input polling 3017825579 169749964
0 2.71e3 .06
drop active 38 42
0 2.52e3 1.11
error-drop active 38 42
0 2.56e3 1.11
error-punt active 3 3
0 2.03e3 1.00
ethernet-input active 5724213 169749964
0 2.64e1 29.65
example-c active 5724169 169749914
0 1.22e1 29.65
icmp6-neighbor-advertisement active 3 3
0 4.53e3 1.00
icmp6-neighbor-solicitation active 6 6
0 1.01e4 1.00
icmp6-router-solicitation active 16 16
0 5.04e3 1.00
interface-output active 4 4
0 3.25e3 1.00
ip4-drop active 2 6
0 4.53e2 3.00
ip4-icmp-echo-request active 2 2
0 1.61e4 1.00
ip4-icmp-input active 2 2
0 3.39e3 1.00
ip4-input active 5724172 169749919
0 3.82e1 29.65
ip4-load-balance active 5724170 169749913
0 1.51e1 29.65
ip4-lookup active 5724172 169749919
0 2.52e1 29.65
ip4-receive active 2 2
0 4.30e3 1.00
ip4-rewrite active 5724170 169749913
0 3.95e1 29.65
ip6-drop active 32 32
0 1.56e3 1.00
ip6-glean active 2 2
0 1.44e4 1.00
ip6-icmp-echo-request active 4 4
0 2.88e3 1.00
ip6-icmp-input active 29 29
0 2.52e3 1.00
ip6-input active 41 43
0 2.73e3 1.05
ip6-link-local active 5 5
0 1.46e3 1.00
ip6-local-hop-by-hop active 4 4
0 3.63e3 1.00
ip6-lookup active 18 18
0 3.20e3 1.00
ip6-mfib-forward-lookup active 32 34
0 4.48e3 1.06
ip6-mfib-forward-rpf active 32 34
0 4.91e3 1.06
ip6-punt active 3 3
0 1.15e3 1.00
ip6-receive active 37 39
0 5.13e3 1.05
ip6-replicate active 28 30
0 4.00e3 1.07
ip6-rewrite active 2 2
0 4.88e3 1.00
ip6-rewrite-mcast active 2 2
0 4.52e3 1.00
punt active 3 3
0 2.45e3 1.00
Thread 0 vpp_main (lcore 0)
Time 260.2, 10 sec internal node vector rate 0.00 loops/sec 1823980.59
vector rates in 0.0000e0, out 1.5423e-2, drop 0.0000e0, punt 0.0000e0
Name State Calls Vectors
Suspends Clocks Vectors/Call
GigabitEthernet6/0/0-output active 2 2
0 1.83e4 1.00
GigabitEthernet6/0/0-tx active 2 2
0 2.14e4 1.00
GigabitEthernet7/0/0-output active 2 2
0 1.40e4 1.00
GigabitEthernet7/0/0-tx active 2 2
0 2.13e4 1.00
acl-plugin-fa-cleaner-process "event wait" 0 0
1 2.01e4 0.00
admin-up-down-process "event wait" 0 0
1 4.61e4 0.00
api-rx-from-ring "any wait" 0 0
19 1.10e6 0.00
avf-process "event wait" 0 0
1 1.65e4 0.00
bfd-process "event wait" 0 0
1 1.12e4 0.00
bond-process "event wait" 0 0
1 8.26e3 0.00
cnat-scanner-process "event wait" 0 0
1 7.62e4 0.00
deleted-722 "not started 1 0
0 3.06e4 0.00
dhcp-client-process "any wait" 0 0
1 1.26e4 0.00
dhcp6-client-cp-process "any wait" 0 0
1 1.13e4 0.00
dhcp6-pd-client-cp-process "any wait" 0 0
1 1.25e4 0.00
dhcp6-pd-reply-publisher-proce"event wait" 0 0
1 1.22e4 0.00
dhcp6-reply-publisher-process "event wait" 0 0
1 1.28e4 0.00
dpdk-process "any wait" 0 0
396 1.11e5 0.00
fib-walk "any wait" 0 0
130 1.07e4 0.00
flow-report-process "any wait" 0 0
1 8.79e3 0.00
flowprobe-timer-process "any wait" 0 0
1 2.93e4 0.00
igmp-timer-process "event wait" 0 0
1 2.75e4 0.00
ikev2-manager-process "event wait" 0 0
1 2.67e4 0.00
ioam-export-process "any wait" 0 0
1 1.54e4 0.00
ip-neighbor-event "event wait" 0 0
1 8.08e3 0.00
ip4-full-reassembly-expire-wal "any wait" 0 0
5198 5.18e3 0.00
ip4-neighbor-age-process "event wait" 0 0
1 7.04e3 0.00
ip4-sv-reassembly-expire-walk "any wait" 0 0
26 6.09e3 0.00
ip6-full-reassembly-expire-wal "any wait" 0 0
5198 5.72e3 0.00
ip6-mld-process "any wait" 0 0
260 5.30e3 0.00
ip6-neighbor-age-process "event wait" 0 0
1 1.51e4 0.00
ip6-ra-process "any wait" 0 0
260 5.05e3 0.00
ip6-rewrite-mcast active 2 2
0 7.26e3 1.00
ip6-rs-process "any wait" 0 0
1 8.24e3 0.00
ip6-sv-reassembly-expire-walk "any wait" 0 0
26 8.23e3 0.00
l2-arp-term-publisher "event wait" 0 0
1 1.01e4 0.00
l2fib-mac-age-scanner-process "event wait" 0 0
1 8.99e3 0.00
lldp-process "event wait" 0 0
1 6.29e6 0.00
memif-process "event wait" 0 0
1 3.91e4 0.00
nat44-ei-ha-process "event wait" 0 0
1 3.76e4 0.00
nsh-md2-ioam-export-process "any wait" 0 0
1 9.34e4 0.00
rd-cp-process "any wait" 0 0
1 1.52e4 0.00
send-dhcp6-client-message-proc "any wait" 0 0
1 2.29e4 0.00
send-dhcp6-pd-client-message-p "any wait" 0 0
1 2.76e4 0.00
sflow-process-samples "any wait" 0 0
260 7.64e3 0.00
startup-config-process "not started 1 0
1 1.57e4 0.00
statseg-collector-process "suspended" 0 0
26 2.53e6 0.00
udp-ping-process "any wait" 0 0
1 3.43e4 0.00
unix-cli-new-session "any wait" 0 0
23 5.42e3 0.00
unix-cli-process-0 "running" 9 0
20 1.98e6 0.00
vhost-user-process "any wait" 0 0
1 4.52e4 0.00
vhost-user-send-interrupt-proc "any wait" 0 0
1 2.50e4 0.00
vpe-link-state-process "event wait" 0 0
3 5.45e3 0.00
vrrp-periodic-process "event wait" 0 0
1 3.91e4 0.00
vxlan-gpe-ioam-export-process "any wait" 0 0
1 1.84e4 0.00
wg-timer-manager "event wait" 0 0
1 2.50e6 0.00
---------------
Thread 1 vpp_wk_0 (lcore 1)
Time 260.2, 10 sec internal node vector rate 29.45 loops/sec 12044011.17
vector rates in 6.2325e5, out 6.2154e5, drop 1.6146e-1, punt 1.5423e-2
Name State Calls Vectors
Suspends Clocks Vectors/Call
GigabitEthernet6/0/0-output active 5 5
0 3.87e3 1.00
GigabitEthernet6/0/0-tx active 5 5
0 1.63e4 1.00
GigabitEthernet7/0/0-output active 5423198 162165848
0 1.27e1 29.90
GigabitEthernet7/0/0-tx active 5423198 161722837
0 1.70e2 29.82
arp-input active 2 2
0 7.63e3 1.00
arp-reply active 2 2
0 6.07e4 1.00
dpdk-input polling 3011191031 162165897
0 2.75e3 .05
drop active 38 42
0 2.61e3 1.11
error-drop active 38 42
0 2.70e3 1.11
error-punt active 4 4
0 1.90e3 1.00
ethernet-input active 5423239 162165897
0 2.78e1 29.90
example active 5423194 162165846
0 1.19e1 29.90
icmp6-neighbor-advertisement active 4 4
0 8.57e3 1.00
icmp6-neighbor-solicitation active 6 6
0 1.91e4 1.00
icmp6-router-solicitation active 16 16
0 5.32e3 1.00
interface-output active 4 4
0 3.16e3 1.00
ip4-drop active 2 6
0 6.19e2 3.00
ip4-icmp-echo-request active 2 2
0 2.15e4 1.00
ip4-icmp-input active 2 2
0 4.39e3 1.00
ip4-input active 5423197 162165851
0 3.89e1 29.90
ip4-load-balance active 5423195 162165845
0 1.50e1 29.90
ip4-lookup active 5423197 162165851
0 2.59e1 29.90
ip4-receive active 2 2
0 3.52e3 1.00
ip4-rewrite active 5423195 162165845
0 3.88e1 29.90
ip6-drop active 32 32
0 1.53e3 1.00
ip6-glean active 2 2
0 1.50e4 1.00
ip6-icmp-echo-request active 4 4
0 4.15e3 1.00
ip6-icmp-input active 30 30
0 2.26e3 1.00
ip6-input active 42 44
0 2.99e3 1.05
ip6-link-local active 6 6
0 9.99e3 1.00
ip6-local-hop-by-hop active 4 4
0 2.11e3 1.00
ip6-lookup active 20 20
0 3.13e3 1.00
ip6-mfib-forward-lookup active 32 34
0 4.24e3 1.06
ip6-mfib-forward-rpf active 32 34
0 4.74e3 1.06
ip6-punt active 4 4
0 1.70e3 1.00
ip6-receive active 38 40
0 4.63e3 1.05
ip6-replicate active 28 30
0 4.10e3 1.07
ip6-rewrite active 2 2
0 5.32e3 1.00
ip6-rewrite-mcast active 2 2
0 5.00e3 1.00
punt active 4 4
0 2.74e3 1.00
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#26570): https://lists.fd.io/g/vpp-dev/message/26570
Mute This Topic: https://lists.fd.io/mt/116254824/21656
Group Owner: [email protected]
Unsubscribe: https://lists.fd.io/g/vpp-dev/leave/14379924/21656/631435203/xyzzy
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-