diff options
author | 2018-05-28 17:56:18 +0200 | |
---|---|---|
committer | 2018-05-29 09:05:50 +0200 | |
commit | bed970cdde06918fe600340a98337a0f9707f3bf (patch) | |
tree | e9dce8dae2566929ba6dd0758132be6388093756 /it/jvpp-benchmark/src | |
parent | fb10579575c4cdc9c4de330c955cc470a8ca8892 (diff) |
jvpp-benchmark: measure classifyAddDelTable
Synchronously creates classify tables.
By default 20x2s warmup
and 100x2s measurement iterations are performed.
VPP is restarted after each iteration.
Each invocation of classifyAddDelTable uses tables
from precomputed set of size tableSetSize.
Tables from the set are used in round-robin fashion.
Run with:
sudo java -jar ./target/jvpp-benchmark-exec.jar \
ClassifyTableCreateBenchmark
To specify aclSetSize (default=100), use:
sudo java -jar ./target/jvpp-benchmark-exec.jar \
ClassifyTableCreateBenchmark -p tableSetSize=1000
To see more options, use
java -jar ./target/jvpp-benchmark-exec.jar -h
Change-Id: I387d879bc99dce45f93d66e8a99f7206f067b443
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'it/jvpp-benchmark/src')
8 files changed, 270 insertions, 7 deletions
diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProvider.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProvider.java index b00f5b90a..f3459916e 100644 --- a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProvider.java +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.fd.hc2vpp.it.jvpp.benchmark; +package io.fd.hc2vpp.it.jvpp.benchmark.acl; import io.fd.vpp.jvpp.acl.dto.AclAddReplace; diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProviderImpl.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProviderImpl.java index 98894fe1d..ca0ddbb8f 100644 --- a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProviderImpl.java +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProviderImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.fd.hc2vpp.it.jvpp.benchmark; +package io.fd.hc2vpp.it.jvpp.benchmark.acl; import io.fd.vpp.jvpp.acl.dto.AclAddReplace; import io.fd.vpp.jvpp.acl.types.AclRule; diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclUpdateBenchmark.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java index 3ec7be953..e8bf2a833 100644 --- a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/AclUpdateBenchmark.java +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclUpdateBenchmark.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.fd.hc2vpp.it.jvpp.benchmark; +package io.fd.hc2vpp.it.jvpp.benchmark.acl; -import static io.fd.hc2vpp.it.jvpp.benchmark.AclUpdateBenchmark.InterfaceMode.L2; -import static io.fd.hc2vpp.it.jvpp.benchmark.AclUpdateBenchmark.InterfaceMode.L3; +import static io.fd.hc2vpp.it.jvpp.benchmark.acl.AclUpdateBenchmark.InterfaceMode.L2; +import static io.fd.hc2vpp.it.jvpp.benchmark.acl.AclUpdateBenchmark.InterfaceMode.L3; import com.google.common.io.CharStreams; import io.fd.vpp.jvpp.JVppRegistryImpl; @@ -58,7 +58,6 @@ import org.openjdk.jmh.annotations.Warmup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @BenchmarkMode(Mode.AverageTime) @State(Scope.Thread) @Fork(1) @@ -86,6 +85,7 @@ public class AclUpdateBenchmark { @Benchmark public void testMethod() throws Exception { + // In real application, reply may be ignored by the caller, so we ignore as well. jvppAcl.aclAddReplace(aclProvider.next()).toCompletableFuture().get(); } diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java new file mode 100644 index 000000000..32700933e --- /dev/null +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableCreateBenchmark.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.it.jvpp.benchmark.classify; + +import com.google.common.io.CharStreams; +import io.fd.vpp.jvpp.JVppRegistryImpl; +import io.fd.vpp.jvpp.core.JVppCoreImpl; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Timeout; +import org.openjdk.jmh.annotations.Warmup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@BenchmarkMode(Mode.AverageTime) +@State(Scope.Thread) +@Fork(1) +@Threads(1) +@Timeout(time = 5) +@Warmup(iterations = 20, time = 2) +@Measurement(iterations = 100, time = 2) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class ClassifyTableCreateBenchmark { + private static final Logger LOG = LoggerFactory.getLogger(ClassifyTableCreateBenchmark.class); + + @Param( {"100"}) + private int tableSetSize; + + private JVppRegistryImpl registry; + private FutureJVppCoreFacade jvppCore; + private ClassifyTableProvider classifyTableProvider; + + @Benchmark + public ClassifyAddDelTableReply testMethod() throws Exception { + // Caller may want to process reply, so return it to prevent JVM from dead code elimination + return jvppCore.classifyAddDelTable(classifyTableProvider.next()).toCompletableFuture().get(); + } + + @Setup(Level.Iteration) + public void setup() throws Exception { + initProvider(); + startVpp(); + connect(); + } + + @TearDown(Level.Iteration) + public void tearDown() throws Exception { + disconnect(); + stopVpp(); + } + + private void initProvider() { + classifyTableProvider = new ClassifyTableProviderImpl(tableSetSize); + } + + private void startVpp() throws Exception { + LOG.info("Starting VPP ..."); + final String[] cmd = {"/bin/sh", "-c", "sudo service vpp start"}; + exec(cmd); + LOG.info("VPP started successfully"); + } + + private void stopVpp() throws Exception { + LOG.info("Stopping VPP ..."); + final String[] cmd = {"/bin/sh", "-c", "sudo service vpp stop"}; + exec(cmd); + + // Wait to be sure VPP was stopped. + // Prevents VPP start failure: "vpp.service: Start request repeated too quickly". + Thread.sleep(1500); + LOG.info("VPP stopped successfully"); + } + + private static void exec(String[] command) throws IOException, InterruptedException { + Process process = Runtime.getRuntime().exec(command); + process.waitFor(); + if (process.exitValue() != 0) { + String error_msg = "Failed to execute " + Arrays.toString(command) + ": " + + CharStreams.toString(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8)); + throw new IllegalStateException(error_msg); + } + } + + private void connect() throws IOException { + LOG.info("Connecting to JVPP ..."); + registry = new JVppRegistryImpl("ACLUpdateBenchmark"); + jvppCore = new FutureJVppCoreFacade(registry, new JVppCoreImpl()); + LOG.info("Successfully connected to JVPP"); + } + + private void disconnect() throws Exception { + LOG.info("Disconnecting ..."); + jvppCore.close(); + registry.close(); + LOG.info("Successfully disconnected ..."); + } +} diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProvider.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProvider.java new file mode 100644 index 000000000..e23ecc6a1 --- /dev/null +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProvider.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.it.jvpp.benchmark.classify; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; + +interface ClassifyTableProvider { + ClassifyAddDelTable next(); +} diff --git a/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImpl.java b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImpl.java new file mode 100644 index 000000000..80ebdccd2 --- /dev/null +++ b/it/jvpp-benchmark/src/main/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImpl.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.it.jvpp.benchmark.classify; + +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import java.io.Serializable; +import java.util.Random; +import javax.annotation.concurrent.NotThreadSafe; + +@NotThreadSafe +class ClassifyTableProviderImpl implements ClassifyTableProvider { + /** + * Static seed to make rnd.nextBytes() output the same for all test run. + */ + private static final long SEED = -2084670072119134328L; + private final int tableSetSize; + private final ClassifyAddDelTable[] tables; + private final Random rnd = new Random(SEED); + + /** + * Pointer to Classify table to be returned by invocation of {@link #next()} method. + */ + private int currentTable = 0; + + ClassifyTableProviderImpl(final int tableSetSize) { + this.tableSetSize = tableSetSize; + tables = new ClassifyAddDelTable[tableSetSize]; + initTables(tableSetSize); + } + + @Override + public ClassifyAddDelTable next() { + final ClassifyAddDelTable result = tables[currentTable]; + currentTable = (currentTable + 1) % tableSetSize; + return result; + } + + private void initTables(final int tableSetSize) { + for (int i = 0; i < tableSetSize; ++i) { + tables[i] = createTable(); + } + } + + private ClassifyAddDelTable createTable() { + final ClassifyAddDelTable addDelTable = new ClassifyAddDelTable(); + addDelTable.isAdd = 1; + addDelTable.tableIndex = -1; + addDelTable.nbuckets = 2; + addDelTable.memorySize = 2 << 20; + addDelTable.nextTableIndex = ~0; + addDelTable.missNextIndex = ~0; + addDelTable.skipNVectors = 0; + addDelTable.matchNVectors = 1; + addDelTable.mask = new byte[16]; + rnd.nextBytes(addDelTable.mask); + return addDelTable; + } +} diff --git a/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProviderImplTest.java b/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProviderImplTest.java index fd4b0d7ff..d54d178e1 100644 --- a/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/AclProviderImplTest.java +++ b/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/acl/AclProviderImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.fd.hc2vpp.it.jvpp.benchmark; +package io.fd.hc2vpp.it.jvpp.benchmark.acl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImplTest.java b/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImplTest.java new file mode 100644 index 000000000..8f11077e0 --- /dev/null +++ b/it/jvpp-benchmark/src/test/java/io/fd/hc2vpp/it/jvpp/benchmark/classify/ClassifyTableProviderImplTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.it.jvpp.benchmark.classify; + +import static org.junit.Assert.*; + +import io.fd.vpp.jvpp.acl.dto.AclAddReplace; +import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable; +import org.junit.Test; + +public class ClassifyTableProviderImplTest { + @Test + public void testTablesDiffer() throws Exception { + final ClassifyTableProviderImpl provider = new ClassifyTableProviderImpl(2); + final ClassifyAddDelTable table0 = provider.next(); + final ClassifyAddDelTable table1 = provider.next(); + final ClassifyAddDelTable table2 = provider.next(); + final ClassifyAddDelTable table3 = provider.next(); + + // Test if ACLs are provided in round-robin fashion + assertEquals("Tables 0 and 2 should be equal", table0, table2); + assertEquals("Tables 1 and 3 should be equal", table1, table3); + assertNotEquals("Tables 0 and 1 should be different", table0, table1); + } +}
\ No newline at end of file |