Skip to content

Commit

Permalink
Add some simple initial benchmarks to hello world standalone
Browse files Browse the repository at this point in the history
* Adds google benchmark dependency
* Adds a plaintext hello_world implementation for comparison
* Adds a benchmark suite to C++ standalone implementation

See go/oak-session-benchmark-results

Change-Id: Ib146669491fc61fa8482e64974c849a206d8f4c8
  • Loading branch information
jblebrun committed Jan 31, 2025
1 parent 142c5cd commit b34d9f4
Show file tree
Hide file tree
Showing 10 changed files with 389 additions and 0 deletions.
10 changes: 10 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ http_archive(
],
)

# GoogleBenchmark
# https://github.com/google/benchmark
http_archive(
name = "com_github_google_benchmark",
strip_prefix = "benchmark-1.9.1",
urls = [
"https://github.com/google/benchmark/archive/refs/tags/v1.9.1.zip",
],
)

# C++ gRPC support.
# https://github.com/grpc/grpc
http_archive(
Expand Down
21 changes: 21 additions & 0 deletions cc/containers/hello_world_enclave_app/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,27 @@ cc_test(
],
)

cc_binary(
name = "standalone_benchmark",
testonly = True,
srcs = ["standalone_benchmark.cc"],
deps = [
":app_service",
"//cc/attestation/verification:insecure_attestation_verifier",
"//cc/client",
"//cc/client:session_client",
"//cc/containers/sdk/standalone:oak_standalone",
"//cc/oak_session:client_session",
"//cc/transport:grpc_streaming_transport",
"//cc/transport:grpc_sync_session_client_transport",
"//oak_containers/examples/hello_world/proto:hello_world_cc_grpc",
"@com_github_google_benchmark//:benchmark",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:status_matchers",
],
)

pkg_tar(
name = "tar",
srcs = [":main"],
Expand Down
6 changes: 6 additions & 0 deletions cc/containers/hello_world_enclave_app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ C++ implementation of the enclave app part (inside the TEE) of the Oak
Containers Hello World example application. This implementation parallels the
Rust implementation in
[`/oak_containers/examples/hello_world/enclave_app`](../../../oak_containers/examples/hello_world/enclave_app).

## Benchmarks

To get some basic benchmark statistics:

bazel run cc/containers/hello_world_enclave_app:standalone_benchmark
14 changes: 14 additions & 0 deletions cc/containers/hello_world_enclave_app/app_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

namespace oak::containers::hello_world_enclave_app {

using ::oak::session::v1::PlaintextMessage;
using ::oak::session::v1::RequestWrapper;
using ::oak::session::v1::ResponseWrapper;
using ::oak::session::v1::SessionRequest;
Expand Down Expand Up @@ -85,4 +86,17 @@ grpc::Status EnclaveApplicationImpl::OakSession(
return grpc::Status();
}

grpc::Status EnclaveApplicationImpl::PlaintextSession(
grpc::ServerContext* context,
grpc::ServerReaderWriter<PlaintextMessage, PlaintextMessage>* stream) {
PlaintextMessage request;
while (stream->Read(&request)) {
std::string response_text = HandleRequest(request.plaintext());
PlaintextMessage response;
*(response.mutable_plaintext()) = response_text;
stream->Write(response);
}
return grpc::Status();
}

} // namespace oak::containers::hello_world_enclave_app
6 changes: 6 additions & 0 deletions cc/containers/hello_world_enclave_app/app_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class EnclaveApplicationImpl
oak::session::v1::SessionRequest>* stream)
override;

grpc::Status PlaintextSession(
grpc::ServerContext* context,
grpc::ServerReaderWriter<oak::session::v1::PlaintextMessage,
oak::session::v1::PlaintextMessage>* stream)
override;

private:
server::OakSessionServer session_server_;
std::string HandleRequest(absl::string_view request);
Expand Down
182 changes: 182 additions & 0 deletions cc/containers/hello_world_enclave_app/standalone_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright 2025 The Project Oak Authors
*
* 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.
*/

#include <cstdint>

#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status_matchers.h"
#include "benchmark/benchmark.h"
#include "cc/attestation/verification/insecure_attestation_verifier.h"
#include "cc/client/client.h"
#include "cc/client/session_client.h"
#include "cc/containers/hello_world_enclave_app/app_service.h"
#include "cc/containers/sdk/standalone/oak_standalone.h"
#include "cc/oak_session/channel/oak_session_channel.h"
#include "cc/oak_session/client_session.h"
#include "cc/transport/grpc_streaming_transport.h"
#include "cc/transport/grpc_sync_session_client_transport.h"
#include "grpcpp/server.h"
#include "grpcpp/server_builder.h"
#include "oak_containers/examples/hello_world/proto/hello_world.grpc.pb.h"

using ::oak::attestation::v1::AttestationResults;
using ::oak::attestation::verification::InsecureAttestationVerifier;
using ::oak::client::OakClient;
using ::oak::containers::example::EnclaveApplication;
using ::oak::containers::hello_world_enclave_app::EnclaveApplicationImpl;
using ::oak::crypto::EncryptionKeyProvider;
using ::oak::crypto::KeyPair;
using ::oak::session::v1::EndorsedEvidence;
using ::oak::session::v1::PlaintextMessage;
using ::oak::session::v1::SessionResponse;
using ::oak::transport::GrpcStreamingTransport;

namespace oak::containers::sdk::standalone {

namespace {

std::string TestMessage(int size) {
std::string message;
message.reserve(size);
for (int i = 0; i < size; i++) {
message += i % 255;
}
return message;
}

constexpr absl::string_view kApplicationConfig = "{}";

class HelloWorldStandaloneBench : public benchmark::Fixture {
public:
void SetUp(benchmark::State& state) override {
// Set up our new Keypair and get an EndorsedEvidence from Rust.
absl::StatusOr<KeyPair> key_pair = KeyPair::Generate();
QCHECK_OK(key_pair);
absl::StatusOr<EndorsedEvidence> endorsed_evidence =
GetEndorsedEvidence(*key_pair);
QCHECK_OK(endorsed_evidence);

// Verify that the endorsed evidence is valid.
InsecureAttestationVerifier verifier;
absl::StatusOr<AttestationResults> attestation_results = verifier.Verify(
std::chrono::system_clock::now(), endorsed_evidence->evidence(),
endorsed_evidence->endorsements());
QCHECK_OK(attestation_results);

service_ = std::make_unique<EnclaveApplicationImpl>(
OakSessionContext(std::move(*endorsed_evidence),
std::make_unique<EncryptionKeyProvider>(*key_pair)),
kApplicationConfig);

grpc::ServerBuilder builder;
builder.AddListeningPort("[::]:8080", grpc::InsecureServerCredentials());
builder.RegisterService(service_.get());
server_ = builder.BuildAndStart();

auto channel = grpc::CreateChannel("localhost:8080",
grpc::InsecureChannelCredentials());
stub_ = EnclaveApplication::NewStub(channel);
}

protected:
std::unique_ptr<EnclaveApplicationImpl> service_;
std::unique_ptr<grpc::Server> server_;
std::unique_ptr<EnclaveApplication::Stub> stub_;
};

BENCHMARK_DEFINE_F(HelloWorldStandaloneBench, HPKEInvocation)
(benchmark::State& state) {
std::string test_message = TestMessage(state.range(0));
grpc::ClientContext context;
auto transport =
std::make_unique<GrpcStreamingTransport>(stub_->LegacySession(&context));
InsecureAttestationVerifier verifier;
auto client = OakClient::Create(std::move(transport), verifier);
QCHECK_OK(client);

for (auto iter : state) {
auto result = (*client)->Invoke(test_message);
QCHECK_OK(result);
QCHECK(*result ==
absl::Substitute("Hello from the enclave, $1! Btw, the app has a "
"config with a length of $0 bytes.",
kApplicationConfig.size(), test_message));
}
state.SetBytesProcessed(int64_t(state.iterations()) *
int64_t(state.range(0)));
}

BENCHMARK_DEFINE_F(HelloWorldStandaloneBench, NoiseInvocation)
(benchmark::State& state) {
std::string test_message = TestMessage(state.range(0));
client::OakSessionClient session_client;
grpc::ClientContext context;
auto channel = session_client.NewChannel(
std::make_unique<transport::GrpcSyncSessionClientTransport>(
stub_->OakSession(&context)));
QCHECK_OK(channel);

for (auto i : state) {
auto result = (*channel)->Send(test_message);
QCHECK_OK(result);
auto response = (*channel)->Receive();
QCHECK_OK(response);
QCHECK(*response ==
absl::Substitute("Hello from the enclave, $1! Btw, the app has a "
"config with a length of $0 bytes.",
kApplicationConfig.size(), test_message));
}
state.SetBytesProcessed(int64_t(state.iterations()) *
int64_t(state.range(0)));
}

BENCHMARK_DEFINE_F(HelloWorldStandaloneBench, PlaintextInvocation)
(benchmark::State& state) {
std::string test_message = TestMessage(state.range(0));
grpc::ClientContext context;
auto reader_writer = stub_->PlaintextSession(&context);

for (auto _ : state) {
PlaintextMessage request;
request.set_plaintext(test_message);
bool result = reader_writer->Write(request);
QCHECK(result);
PlaintextMessage response;
bool response_result = reader_writer->Read(&response);
QCHECK(response_result);
QCHECK(response.plaintext() ==
absl::Substitute("Hello from the enclave, $1! Btw, the app has a "
"config with a length of $0 bytes.",
kApplicationConfig.size(), test_message));
}
state.SetBytesProcessed(int64_t(state.iterations()) *
int64_t(state.range(0)));
}

BENCHMARK_REGISTER_F(HelloWorldStandaloneBench, HPKEInvocation)
->Range(2, 1 << 21);
BENCHMARK_REGISTER_F(HelloWorldStandaloneBench, NoiseInvocation)
->Range(2, 1 << 21);
BENCHMARK_REGISTER_F(HelloWorldStandaloneBench, PlaintextInvocation)
->Range(2, 1 << 21);

} // namespace

} // namespace oak::containers::sdk::standalone

// Run the benchmark
BENCHMARK_MAIN();
17 changes: 17 additions & 0 deletions cc/oak_session/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@ cc_test(
],
)

cc_binary(
name = "client_server_session_benchmark",
testonly = True,
srcs = ["client_server_session_benchmark.cc"],
tags = ["asan"],
deps = [
":client_session",
":server_session",
"//proto/session:session_cc_proto",
"@com_github_google_benchmark//:benchmark",
"@com_github_grpc_grpc//:grpc++",
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status:status_matchers",
],
)

cc_library(
name = "config",
srcs = ["config.cc"],
Expand Down
Loading

0 comments on commit b34d9f4

Please sign in to comment.