-
Notifications
You must be signed in to change notification settings - Fork 14
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 Analyses for DPDK Applications Using the Ethdev Library #83
base: master
Are you sure you want to change the base?
Performance Analyses for DPDK Applications Using the Ethdev Library #83
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor changes.
* @author Adel Belkhiri | ||
*/ | ||
@SuppressWarnings({ "nls" }) | ||
public interface Attributes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend renaming to EthAttributes or something more descriptive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comments Matthew. I renamed it as suggested in the new version.
* | ||
* @author Adel Belkhiri | ||
*/ | ||
@SuppressWarnings({ "nls" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NonNullByDefault
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
try { | ||
StateSystemBuilderUtils.incrementAttributeLong(ssb, ts, queueQuark, nbPkts); | ||
} catch (StateValueTypeException e) { | ||
Activator.getInstance().logWarning(getClass().getName() + ": problem accessing the state of a NIC queue (Quark =" + String.valueOf(queueQuark) + ")"); //$NON-NLS-1$ //$NON-NLS-2$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this... can you put it in the activator to have it everywhere?
* @param ts | ||
* time to use for state change | ||
*/ | ||
static private void createNicQueue(ITmfStateSystemBuilder ssb, int queueSetQuark, int nbQueues, long ts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createNicQueues
updateCounts(ssb, rxQueueQark, Objects.requireNonNull(nbRxPkts), ts); | ||
|
||
} else if (eventName.equals(DpdkEthdevEventLayout.eventEthdevTxqBurst())) { | ||
Integer queueId = event.getContent().getFieldValue(Integer.class, DpdkEthdevEventLayout.fieldQueueId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put in a common helper function, you have it for 100-103 and 108-110
@@ -0,0 +1,109 @@ | |||
package org.eclipse.tracecompass.incubator.internal.dpdk.core.ethdev.rate.analysis; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copyright header
// Event field names | ||
// ------------------------------------------------------------------------ | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs a description too
i++; | ||
} | ||
} catch (IndexOutOfBoundsException e) { | ||
Activator.getInstance().logWarning("A DPDK event (" + DpdkEthdevEventLayout.eventEthdevConfigure() + ") is missing"); //$NON-NLS-1$ //$NON-NLS-2$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
write the index? or just log the exception.
* | ||
* @author Geneviève Bastien | ||
*/ | ||
public class IODataPalette { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reuse for the win!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all the analyses look very interesting but there is a lot of duplicated that can easily be reused throughout. In particular the throughput and rate analysis that are very similar, it could be merged into one analysis with multiple views.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is duplicated throughout the different packages you created. You should only have one version of this file. Also it is missing a copyright header
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Arnauld for the feedback. I have a question: should I just change the name of the file/class for each analysis (example: DpdkEthdevThroughputEventLayout.java), or combine all these files into one single layout class used by all the analyses for Ethdev?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not adding this file to the trace package, and adding it to the DpdkTrace aspects as well ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed all the aspects in the ethdev poll analyses into regular classes. It turns out that aspects are not required for this type of analysis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not merging this analysis and the throughput one ? Both uses 99% the same code, you could merge both and just use 2 different data providers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment Arnaud. Indeed, I merged the throughput and rate analyses, thus, reducing much the duplicated code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
} | ||
} catch (TimeRangeException | AttributeNotFoundException | StateSystemDisposedException e) { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs at least a warning or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could have a parent class for this to reuse most of the code.
0b9fd6f
to
d2f9125
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small changes needed
return nodes; | ||
} | ||
|
||
@Override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @MatthewKhouzam for this comment. Omitting the "@OverRide" annotation results in an error, so I believe we still need it.
/** | ||
* Abstract class for building data series illustrating DPDK NICs throughput. | ||
*/ | ||
protected abstract class AbstractNicQueueBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! I put this class in a separate file and changed its visibility to "package".
return stateValue instanceof Number ? ((Number) stateValue).doubleValue() : 0.0; | ||
} catch (AttributeNotFoundException | IndexOutOfBoundsException e) { | ||
Activator.getInstance().logError("Error accessing packets size on state system", e); //$NON-NLS-1$ | ||
return 0.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be NaN or 0.0? asking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MatthewKhouzam: You are right! thanks.
return stateValue instanceof Number ? ((Number) stateValue).doubleValue() : 0.0; | ||
} catch (AttributeNotFoundException | IndexOutOfBoundsException e) { | ||
Activator.getInstance().logError("Error accessing packets count on state system", e); //$NON-NLS-1$ | ||
return 0.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
NLS.initializeMessages(BUNDLE_NAME, Messages.class); | ||
} | ||
|
||
private Messages() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a //does nothing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
NLS.initializeMessages(BUNDLE_NAME, Messages.class); | ||
} | ||
|
||
private Messages() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@Override | ||
protected ITmfTreeColumnDataProvider getColumnDataProvider() { | ||
return () -> { | ||
return ImmutableList.of( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get away with List.of?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MatthewKhouzam: Yes, we can replace ImmutableList.of() with List.of(). I checked and found that List.of() was introduced in Java 9, making it a suitable replacement here. Thank you for the comment!
NLS.initializeMessages(BUNDLE_NAME, Messages.class); | ||
} | ||
|
||
private Messages() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//do nothing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
d2f9125
to
12cfb9a
Compare
12cfb9a
to
7a8e39d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of small comments, once they are fixed, I will be happy to approve !
@@ -15,8 +15,12 @@ Require-Bundle: org.eclipse.ui, | |||
org.eclipse.tracecompass.tmf.core, | |||
org.eclipse.tracecompass.tmf.ctf.core, | |||
org.eclipse.tracecompass.analysis.os.linux.core, | |||
org.eclipse.jdt.annotation;bundle-version="2.2.400" | |||
org.eclipse.jdt.annotation;bundle-version="2.2.400", | |||
com.google.guava, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be set in Imported packages.
@Override | ||
public boolean canExecute(ITmfTrace trace) { | ||
if (trace instanceof DpdkTrace) { | ||
return ((DpdkTrace) trace).validate(null, trace.getPath()).isOK() ? true : false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use a ternary operator there, you can just return the result from isOk().
@@ -15,8 +15,12 @@ Require-Bundle: org.eclipse.ui, | |||
org.eclipse.tracecompass.tmf.core, | |||
org.eclipse.tracecompass.tmf.ctf.core, | |||
org.eclipse.tracecompass.analysis.os.linux.core, | |||
org.eclipse.jdt.annotation;bundle-version="2.2.400" | |||
com.google.guava, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be in the imported packages section.
org.eclipse.jdt.annotation;bundle-version="2.2.400" | ||
com.google.guava, | ||
org.eclipse.jdt.annotation;bundle-version="2.2.400", | ||
org.eclipse.tracecompass.analysis.lami.core |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be above the org.eclipse.jdt.annotation;bundle-version="2.2.400"
line to make a clearer diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should maybe be in org.eclipse.tracecompass.incubator.internal.dpdk.core.ethdev
prevTime = time; | ||
} | ||
|
||
return ImmutableList.copyOf(Iterables.transform(builders, builder -> builder.build(Y_AXIS_DESCRIPTION))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unchecked conversion warning
|
||
for (Entry<Long, Integer> entry : getSelectedEntries(filter).entrySet()) { | ||
long id = entry.getKey(); | ||
int quark = entry.getValue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two unsafe interpretation, the getKey() and getValue() should be put in a Objects.requireNonNull().
return new AbstractSelectTreeViewer2(parent, 1, DpdkEthdevSpinDataProvider.ID) { | ||
@Override | ||
protected ITmfTreeColumnDataProvider getColumnDataProvider() { | ||
return () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curly braces should be removed, List.of should be changed to ImmutableList to fix the warning
return new AbstractSelectTreeViewer2(parent, 1, DpdkEthdevThroughputBpsDataProvider.ID) { | ||
@Override | ||
protected ITmfTreeColumnDataProvider getColumnDataProvider() { | ||
return () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment.
return new AbstractSelectTreeViewer2(parent, 1, DpdkEthdevThroughputPpsDataProvider.ID) { | ||
@Override | ||
protected ITmfTreeColumnDataProvider getColumnDataProvider() { | ||
return () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment
Introduces packet throughput analysis for DPDK applications using the ethdev library. The analysis calculates packet throughput in both bits per second (bps) and packets per second (pps) for transmitted and received Ethernet traffic on a per-queue basis. Note that the calculation of throughput in bps requires the existence of custom profiling events in the trace Signed-off-by: Adel Belkhiri <[email protected]>
7a8e39d
to
451df36
Compare
PMD threads continuously poll NIC queues, leading to constant 100% CPU usage. This analysis provides a rough estimation of how busy PMD threads are with actual work, by comparing the times they successfully retrieve packets from the NIC queue versus the times they are merely spinning without processing any packets. Signed-off-by: Adel Belkhiri <[email protected]>
Introduce packet distribution analysis for PMD threads based on ethdev library. This analysis computes the distribution of packets retrieved in a single rte_eth_rx_burst() call, on a per-queue basis. Signed-off-by: Adel Belkhiri <[email protected]>
Introduce packet distribution statistics analysis for PMD threads in the ethdev library. This analysis calculates various statistics related to the distribution of packets retrieved in a single rte_eth_rx_burst() call, on a per-thread and per-queue basis. The computed statistics include the minimum, maximum, average number of packets retrieved, as well as the standard deviation. Signed-off-by: Adel Belkhiri <[email protected]>
451df36
to
d21e82b
Compare
This PR introduces 5 performance analyses for DPDK applications implemented using the ethdev library. These analyses provide insights into packet distribution, rate, throughput, and PMD thread busyness, thus helping monitor and optimize application performance.
New Features:
Packet Rate Analysis:
Computes the packet rate (in pps) for transmitted and received Ethernet traffic on a per-queue basis. It helps monitor the efficiency of traffic processing by calculating the number of packets received or transmitted in a given period.
Packet Throughput Analysis:
Analyzes packet throughput (in bps) for transmitted and received Ethernet traffic. This is done on a per-queue basis to evaluate bandwidth usage.
Busyness Analysis for PMD Threads:
Estimates how busy PMD threads are by comparing the times they successfully retrieve packets from the NIC queue versus when they are merely spinning without processing any packets. This can be used to evaluate the efficiency of polling operations.
Packet Distribution Analysis:
Analyzes the distribution of packets retrieved in a single rte_eth_rx_burst() call, on a per-thread and per-queue basis. This analysis provides insights into packet retrieval patterns, including how evenly or unevenly the workload is distributed across queues.
Packet Distribution Statistics:
Computes various statistics related to packet retrieval distribution, including the minimum, maximum, average, and standard deviation for packets retrieved in a single rte_eth_rx_burst() call, which offers more granular visibility into traffic distribution patterns.