From: Thomas Monjalon <thomas@monjalon.net>
To: dev@dpdk.org, techboard@dpdk.org
Cc: "Ajit Khaparde" <ajit.khaparde@broadcom.com>,
"Ananyev, Konstantin" <konstantin.ananyev@intel.com>,
"Andrew Rybchenko" <andrew.rybchenko@oktetlabs.ru>,
dev@dpdk.org, "Yigit, Ferruh" <ferruh.yigit@intel.com>,
david.marchand@redhat.com, "Richardson,
Bruce" <bruce.richardson@intel.com>,
olivier.matz@6wind.com, jerinj@marvell.com,
viacheslavo@nvidia.com, honnappa.nagarahalli@arm.com,
maxime.coquelin@redhat.com, stephen@networkplumber.org,
hemant.agrawal@nxp.com, viacheslavo@nvidia.com,
"Matan Azrad" <matan@nvidia.com>,
"Shahaf Shuler" <shahafs@nvidia.com>,
"Morten Brørup" <mb@smartsharesystems.com>
Subject: Re: [dpdk-dev] [PATCH 15/15] mbuf: move pool pointer in hotterfirst half
Date: Mon, 02 Nov 2020 16:58:08 +0100 [thread overview]
Message-ID: <13044489.RHGIMAnax8@thomas> (raw)
In-Reply-To: <98CBD80474FA8B44BF855DF32C47DC35C613CD@smartserver.smartshare.dk>
+Cc techboard
We need benchmark numbers in order to take a decision.
Please all, prepare some arguments and numbers so we can discuss
the mbuf layout in the next techboard meeting.
01/11/2020 21:59, Morten Brørup:
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > Sent: Sunday, November 1, 2020 5:38 PM
> >
> > 01/11/2020 10:12, Morten Brørup:
> > > One thing has always puzzled me:
> > > Why do we use 64 bits to indicate which memory pool
> > > an mbuf belongs to?
> > > The portid only uses 16 bits and an indirection index.
> > > Why don't we use the same kind of indirection index for mbuf pools?
> >
> > I wonder what would be the cost of indirection. Probably neglectible.
>
> Probably. The portid does it, and that indirection is heavily used everywhere.
>
> The size of mbuf memory pool indirection array should be compile time configurable, like the size of the portid indirection array.
>
> And for reference, the indirection array will fit into one cache line if we default to 8 mbuf pools, thus supporting an 8 CPU socket system with one mbuf pool per CPU socket, or a 4 CPU socket system with two mbuf pools per CPU socket.
>
> (And as a side note: Our application is optimized for single-socket systems, and we only use one mbuf pool. I guess many applications were developed without carefully optimizing for multi-socket systems, and also just use one mbuf pool. In these cases, the mbuf structure doesn't really need a pool field. But it is still there, and the DPDK libraries use it, so we didn't bother removing it.)
>
> > I think it is a good proposal...
> > ... for next year, after a deprecation notice.
> >
> > > I can easily imagine using one mbuf pool (or perhaps a few pools)
> > > per CPU socket (or per physical memory bus closest to an attached NIC),
> > > but not more than 256 mbuf memory pools in total.
> > > So, let's introduce an mbufpoolid like the portid,
> > > and cut this mbuf field down from 64 to 8 bits.
We will need to measure the perf of the solution.
There is a chance for the cost to be too much high.
> > > If we also cut down m->pkt_len from 32 to 24 bits,
> >
> > Who is using packets larger than 64k? Are 16 bits enough?
>
> I personally consider 64k a reasonable packet size limit. Exotic applications with even larger packets would have to live with this constraint. But let's see if there are any objections. For reference, 64k corresponds to ca. 44 Ethernet (1500 byte) packets.
>
> (The limit could be 65535 bytes, to avoid translation of the value 0 into 65536 bytes.)
>
> This modification would go nicely hand in hand with the mbuf pool indirection modification.
>
> ... after yet another round of ABI stability discussions, depreciation notices, and so on. :-)
After more thoughts, I'm afraid 64k is too small in some cases.
And 24-bit manipulation would probably break performance.
I'm afraid we are stuck with 32-bit length.
> > > we can get the 8 bit mbuf pool index into the first cache line
> > > at no additional cost.
> >
> > I like the idea.
> > It means we don't need to move the pool pointer now,
> > i.e. it does not have to replace the timestamp field.
>
> Agreed! Don't move m->pool to the first cache line; it is not used for RX.
>
> >
> > > In other words: This would free up another 64 bit field in the mbuf
> > structure!
> >
> > That would be great!
> >
> >
> > > And even though the m->next pointer for scattered packets resides
> > > in the second cache line, the libraries and application knows
> > > that m->next is NULL when m->nb_segs is 1.
> > > This proves that my suggestion would make touching
> > > the second cache line unnecessary (in simple cases),
> > > even for re-initializing the mbuf.
> >
> > So you think the "next" pointer should stay in the second half of mbuf?
> >
> > I feel you would like to move the Tx offloads in the first half
> > to improve performance of very simple apps.
>
> "Very simple apps" sounds like a minority of apps. I would rather say "very simple packet handling scenarios", e.g. forwarding of normal size non-segmented packets. I would guess that the vast majority of packets handled by DPDK applications actually match this scenario. So I'm proposing to optimize for what I think is the most common scenario.
>
> If segmented packets are common, then m->next could be moved to the first cache line. But it will only improve the pure RX steps of the pipeline. When preparing the packet for TX, m->tx_offloads will need to be set, and the second cache line comes into play. So I'm wondering how big the benefit of having m->next in the first cache line really is - assuming that m->nb_segs will be checked before accessing m->next.
>
> > I am thinking the opposite: we could have some dynamic fields space
> > in the first half to improve performance of complex Rx.
> > Note: we can add a flag hint for field registration in this first half.
> >
>
> I have had the same thoughts. However, I would prefer being able to forward ordinary packets without using the second mbuf cache line at all (although only in specific scenarios like my example above).
>
> Furthermore, the application can abuse the 64 bit m->tx_offload field for private purposes until it is time to prepare the packet for TX and pass it on to the driver. This hack somewhat resembles a dynamic field in the first cache line, and will not be possible if the m->pool or m->next field is moved there.
next prev parent reply other threads:[~2020-11-02 15:58 UTC|newest]
Thread overview: 170+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-29 9:27 [dpdk-dev] [PATCH 00/15] remove mbuf timestamp Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 01/15] eventdev: remove software Rx timestamp Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 02/15] mbuf: add Rx timestamp dynamic flag Thomas Monjalon
2020-10-29 9:58 ` Andrew Rybchenko
2020-10-29 18:19 ` Ajit Khaparde
2020-10-29 9:27 ` [dpdk-dev] [PATCH 03/15] ethdev: register mbuf field and flags for timestamp Thomas Monjalon
2020-10-29 10:08 ` Andrew Rybchenko
2020-10-29 10:12 ` Thomas Monjalon
2020-10-29 10:33 ` Andrew Rybchenko
2020-10-29 10:46 ` Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 04/15] latency: switch timestamp to dynamic mbuf field Thomas Monjalon
2020-10-29 10:13 ` Andrew Rybchenko
2020-10-29 10:40 ` Thomas Monjalon
2020-10-29 14:20 ` Pattan, Reshma
2020-10-29 16:15 ` Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 05/15] net/ark: " Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 06/15] net/dpaa2: " Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 07/15] net/mlx5: fix dynamic mbuf offset lookup check Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 08/15] net/mlx5: switch timestamp to dynamic mbuf field Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 09/15] net/nfb: " Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 10/15] net/octeontx2: " Thomas Monjalon
2020-10-29 11:02 ` Andrew Rybchenko
2020-10-29 11:34 ` Thomas Monjalon
2020-10-29 11:37 ` Andrew Rybchenko
2020-10-29 11:52 ` Slava Ovsiienko
2020-10-30 12:41 ` Jerin Jacob
2020-11-01 16:12 ` Thomas Monjalon
2020-11-01 20:00 ` Andrew Rybchenko
2020-10-29 9:27 ` [dpdk-dev] [PATCH 11/15] net/pcap: " Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 12/15] app/testpmd: " Thomas Monjalon
2020-10-29 10:20 ` Andrew Rybchenko
2020-10-29 10:43 ` Thomas Monjalon
2020-10-29 10:52 ` Andrew Rybchenko
2020-10-29 9:27 ` [dpdk-dev] [PATCH 13/15] examples/rxtx_callbacks: switch timestamp to dynamic field Thomas Monjalon
2020-10-29 10:21 ` Andrew Rybchenko
2020-10-29 10:44 ` Thomas Monjalon
2020-10-29 9:27 ` [dpdk-dev] [PATCH 14/15] mbuf: remove deprecated timestamp field Thomas Monjalon
2020-10-29 10:23 ` Andrew Rybchenko
2020-10-29 18:18 ` Ajit Khaparde
2020-10-29 14:48 ` Kinsella, Ray
2020-10-29 9:27 ` [dpdk-dev] [PATCH 15/15] mbuf: move pool pointer in hotter first half Thomas Monjalon
2020-10-29 10:50 ` Andrew Rybchenko
2020-10-29 10:56 ` Thomas Monjalon
2020-10-29 14:15 ` Ananyev, Konstantin
2020-10-29 18:45 ` Ajit Khaparde
2020-10-31 18:20 ` [dpdk-dev] [PATCH 15/15] mbuf: move pool pointer in hotterfirst half Morten Brørup
2020-10-31 20:40 ` Thomas Monjalon
2020-11-01 9:12 ` Morten Brørup
2020-11-01 16:21 ` Thomas Monjalon
2020-11-01 16:38 ` Thomas Monjalon
2020-11-01 20:59 ` Morten Brørup
2020-11-02 15:58 ` Thomas Monjalon [this message]
2020-11-03 12:10 ` Morten Brørup
2020-11-03 12:25 ` Bruce Richardson
2020-11-03 13:46 ` Morten Brørup
2020-11-03 13:50 ` Bruce Richardson
2020-11-03 14:03 ` Morten Brørup
2020-11-03 14:02 ` Slava Ovsiienko
2020-11-03 15:03 ` Morten Brørup
2020-11-04 15:00 ` Olivier Matz
2020-11-05 0:25 ` Ananyev, Konstantin
2020-11-05 9:04 ` Morten Brørup
2020-11-05 9:35 ` Morten Brørup
2020-11-05 10:29 ` Bruce Richardson
2020-10-29 14:42 ` [dpdk-dev] [PATCH 15/15] mbuf: move pool pointer in hotter first half Kinsella, Ray
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 00/14] remove mbuf timestamp Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 01/14] eventdev: remove software Rx timestamp Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 02/14] mbuf: add Rx timestamp dynamic flag Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 03/14] ethdev: register mbuf field and flags for timestamp Thomas Monjalon
2020-11-02 15:39 ` Olivier Matz
2020-11-02 16:52 ` Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 04/14] latency: switch timestamp to dynamic mbuf field Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 05/14] net/ark: " Thomas Monjalon
2020-11-02 15:32 ` Olivier Matz
2020-11-02 16:10 ` Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 06/14] net/dpaa2: " Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 07/14] net/mlx5: fix dynamic mbuf offset lookup check Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 08/14] net/mlx5: switch timestamp to dynamic mbuf field Thomas Monjalon
2020-11-02 5:08 ` Ruifeng Wang
2020-11-02 23:20 ` David Christensen
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 09/14] net/nfb: " Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 10/14] net/octeontx2: " Thomas Monjalon
2020-11-01 18:28 ` Jerin Jacob
2020-11-02 9:38 ` Thomas Monjalon
2020-11-02 11:01 ` Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 11/14] net/pcap: " Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 12/14] app/testpmd: " Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 13/14] examples/rxtx_callbacks: switch timestamp to dynamic field Thomas Monjalon
2020-11-01 18:06 ` [dpdk-dev] [PATCH v2 14/14] mbuf: remove deprecated timestamp field Thomas Monjalon
2020-11-02 15:41 ` Olivier Matz
2020-11-02 15:47 ` David Marchand
2020-11-02 15:49 ` Thomas Monjalon
2020-11-01 18:08 ` [dpdk-dev] [PATCH v2 00/14] remove mbuf timestamp Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 00/16] " Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 01/16] eventdev: remove software Rx timestamp Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 02/16] mbuf: add Rx timestamp flag and helpers Thomas Monjalon
2020-11-03 9:33 ` Olivier Matz
2020-11-03 9:59 ` Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 03/16] latency: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 04/16] net/ark: " Thomas Monjalon
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 05/16] net/dpaa2: " Thomas Monjalon
2020-11-03 9:18 ` Hemant Agrawal
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 06/16] net/mlx5: fix dynamic mbuf offset lookup check Thomas Monjalon
2020-11-03 8:12 ` Slava Ovsiienko
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 07/16] net/mlx5: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 8:12 ` Slava Ovsiienko
2020-11-03 0:13 ` [dpdk-dev] [PATCH v3 08/16] net/nfb: " Thomas Monjalon
2020-11-03 10:20 ` Olivier Matz
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 09/16] net/octeontx2: " Thomas Monjalon
2020-11-03 10:52 ` Harman Kalra
2020-11-03 11:22 ` Thomas Monjalon
2020-11-03 12:21 ` Thomas Monjalon
2020-11-03 14:23 ` [dpdk-dev] [EXT] " Harman Kalra
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 10/16] net/pcap: " Thomas Monjalon
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 11/16] app/testpmd: " Thomas Monjalon
2020-11-03 10:23 ` Olivier Matz
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 12/16] examples/rxtx_callbacks: switch timestamp to dynamic field Thomas Monjalon
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 13/16] ethdev: add doxygen comment for Rx timestamp API Thomas Monjalon
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 14/16] mbuf: remove deprecated timestamp field Thomas Monjalon
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 15/16] mbuf: add Tx timestamp registration helper Thomas Monjalon
2020-11-03 0:14 ` [dpdk-dev] [PATCH v3 16/16] ethdev: include mbuf registration in Tx timestamp API Thomas Monjalon
2020-11-03 7:54 ` Slava Ovsiienko
2020-11-03 9:00 ` [dpdk-dev] [PATCH v3 00/16] remove mbuf timestamp David Marchand
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 " Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 01/16] eventdev: remove software Rx timestamp Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 02/16] mbuf: add Rx timestamp flag and helpers Thomas Monjalon
2020-11-03 12:34 ` Andrew Rybchenko
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 03/16] latency: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 04/16] net/ark: " Thomas Monjalon
2020-11-03 12:37 ` Andrew Rybchenko
2020-11-03 13:08 ` Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 05/16] net/dpaa2: " Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 06/16] net/mlx5: fix dynamic mbuf offset lookup check Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 07/16] net/mlx5: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 08/16] net/nfb: " Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 09/16] net/octeontx2: " Thomas Monjalon
2020-11-03 12:21 ` [dpdk-dev] [PATCH v4 10/16] net/pcap: " Thomas Monjalon
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 11/16] app/testpmd: " Thomas Monjalon
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 12/16] examples/rxtx_callbacks: switch timestamp to dynamic field Thomas Monjalon
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 13/16] ethdev: add doxygen comment for Rx timestamp API Thomas Monjalon
2020-11-03 12:40 ` Andrew Rybchenko
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 14/16] mbuf: remove deprecated timestamp field Thomas Monjalon
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 15/16] mbuf: add Tx timestamp registration helper Thomas Monjalon
2020-11-03 12:42 ` Andrew Rybchenko
2020-11-03 12:22 ` [dpdk-dev] [PATCH v4 16/16] ethdev: include mbuf registration in Tx timestamp API Thomas Monjalon
2020-11-03 12:45 ` Andrew Rybchenko
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 00/16] remove mbuf timestamp Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 01/16] eventdev: remove software Rx timestamp Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 02/16] mbuf: add Rx timestamp flag and helpers Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 03/16] latency: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 04/16] net/ark: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 05/16] net/dpaa2: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 06/16] net/mlx5: fix dynamic mbuf offset lookup check Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 07/16] net/mlx5: switch Rx timestamp to dynamic mbuf field Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 08/16] net/nfb: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 09/16] net/octeontx2: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 10/16] net/pcap: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 11/16] app/testpmd: " Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 12/16] examples/rxtx_callbacks: switch timestamp to dynamic field Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 13/16] ethdev: add doxygen comment for Rx timestamp API Thomas Monjalon
2020-11-03 19:07 ` Ajit Khaparde
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 14/16] mbuf: remove deprecated timestamp field Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 15/16] mbuf: add Tx timestamp registration helper Thomas Monjalon
2020-11-03 14:09 ` [dpdk-dev] [PATCH v5 16/16] ethdev: include mbuf registration in Tx timestamp API Thomas Monjalon
2020-11-03 14:17 ` [dpdk-dev] [PATCH v5 00/16] remove mbuf timestamp Olivier Matz
2020-11-03 14:44 ` Thomas Monjalon
2020-11-03 16:08 ` Stephen Hemminger
2020-11-03 16:20 ` Thomas Monjalon
2020-11-03 17:42 ` Stephen Hemminger
2020-11-03 17:55 ` Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=13044489.RHGIMAnax8@thomas \
--to=thomas@monjalon.net \
--cc=ajit.khaparde@broadcom.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=bruce.richardson@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=hemant.agrawal@nxp.com \
--cc=honnappa.nagarahalli@arm.com \
--cc=jerinj@marvell.com \
--cc=konstantin.ananyev@intel.com \
--cc=matan@nvidia.com \
--cc=maxime.coquelin@redhat.com \
--cc=mb@smartsharesystems.com \
--cc=olivier.matz@6wind.com \
--cc=shahafs@nvidia.com \
--cc=stephen@networkplumber.org \
--cc=techboard@dpdk.org \
--cc=viacheslavo@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).