Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4ef9e38
[aws][system] Add C++ dependencies images
mcopik May 3, 2022
2dc3894
[aws][system] Add C++ dependencies images
mcopik May 3, 2022
3dd45ef
[aws] Change name style of C++ Docker images
mcopik May 7, 2022
72b88ad
[aws] Add AWS C++ Lambda runtime as dependency
mcopik May 7, 2022
1cdcc74
[aws] Add the basic wrapper for C++
mcopik May 7, 2022
17c69fe
[aws] Add Docker build container for C++
mcopik May 7, 2022
53f81f7
[benchmarks] Add sleep benchmark implementation for C++
mcopik May 7, 2022
67560c8
[aws] Define necessary package files for C++
mcopik May 7, 2022
a9b5218
[system] Add Docker build arguments for C++ images
mcopik May 7, 2022
3c3700c
[aws] Implement correct return from C++
mcopik May 7, 2022
61bbffa
[aws] [system] First version of support for C++ benchmarks
mcopik May 7, 2022
89d29e7
[aws] Add Boost UUID in handler
mcopik May 7, 2022
5db9fc2
[aws] Support HTTP trigger for C++
mcopik May 7, 2022
c6a1a81
[aws] Minor update of C++ dependencies
mcopik May 7, 2022
dc3df69
[aws] Add key-value wrapper for C++ benchmarks
mcopik May 15, 2022
eb5d0b6
[benchmarks] Linting
mcopik May 15, 2022
2f035fc
[system] Add logging of C++ build steps
mcopik May 15, 2022
1c5d85c
[aws] Add Redis wrappers for C++
mcopik May 15, 2022
9a96d72
[aws] Move Dockerfiles to a new directory
mcopik Jun 18, 2025
b5fbb12
[dev] Linting
mcopik Jun 18, 2025
a8239a1
[aws] Rename C++ utility function and apply formatting
mcopik Jun 19, 2025
8e1f93a
[aws] Pin hiredis version
mcopik Jun 19, 2025
b7ab8e4
[aws] Fix merge error
mcopik Jun 19, 2025
068adfd
[aws] Fix various bugs for C++ benchmarks, as pointed out during review
mcopik Jun 19, 2025
ef25201
[aws] Fix generation of cloud runtime
mcopik Jun 20, 2025
3fa330f
[aws] Add architecture configuration for cpp base images. Ensure the …
HoriaMercan Jun 25, 2025
1ff7b98
Implemented 210-thumbnail benchmark in cpp.
HoriaMercan Jun 29, 2025
faf4ffd
[aws] Added docker dependencies for opencv
HoriaMercan Jun 29, 2025
bd9a88a
Delete Base64.hpp file
HoriaMercan Jul 2, 2025
85ff323
Optimize storage.cpp by using boost's bufferstream
HoriaMercan Jul 2, 2025
6ae77be
Added cpp support for graph pagerank
HoriaMercan Jul 7, 2025
6114498
Added C++ in config for Pagerank Benchmark
HoriaMercan Jul 8, 2025
330d543
Added cpp_dependencies config for building CMakeList.txt for thumbnai…
HoriaMercan Jul 8, 2025
53c3c07
Added graph-bfs benchmark in C++ AWS
HoriaMercan Jul 8, 2025
3f55a9d
Added Torch & TorchVIsion dependencies to C++. Added image-recognitio…
HoriaMercan Jul 10, 2025
5a1557d
[lint] Remove dead code
HoriaMercan Oct 13, 2025
b38c604
Merge branch 'master' into cpp_benchmarks
mcopik Oct 27, 2025
9fb0dd3
[dev] Linting
mcopik Oct 27, 2025
bab4ce2
[aws] Fix Boost URL
mcopik Dec 6, 2025
0b25d4b
[system] Fix incorrect logging
mcopik Dec 6, 2025
07b6a8e
Merge branch 'cpp_benchmarks' of github.com:spcl/serverless-benchmark…
mcopik Dec 6, 2025
bf46204
[aws] Add container template for C++ functions
mcopik Dec 6, 2025
6c027de
[AWS-cpp] Fix boost download link
DJAntivenom Nov 28, 2025
c6d5e0e
[types] Fix __str__ method of Language enum
DJAntivenom Nov 28, 2025
a9c35cb
[aws] [system] Separate handling of containers and code packages
mcopik Dec 6, 2025
bba1995
Merge branch 'cpp_benchmarks' of github.com:spcl/serverless-benchmark…
mcopik Dec 6, 2025
27e053d
[aws] Add dynamic resolution of necessary dependencies for C++ contai…
mcopik Dec 7, 2025
38bdbe2
[system] Support storage configuration in regression
mcopik Dec 7, 2025
468cd35
[system] Add examples of configurations for different languages
mcopik Dec 7, 2025
5558f32
[openwhisk] Adapt the OpenWhisk implementation to new container build…
mcopik Dec 7, 2025
3fb59b2
[system] Extend regression with the sleep microbenchmark
mcopik Dec 7, 2025
2c206a6
[docs] Update documentation on storage IP replacement
mcopik Dec 7, 2025
5a893a8
[system] Linting and typing fixes
mcopik Dec 7, 2025
5ee60d5
[system] Bump Python requirements
mcopik Dec 7, 2025
2b1aa03
[system] Update CI config
mcopik Dec 7, 2025
b2fe903
[docs] Update list of benchmarks
mcopik Dec 7, 2025
5ba7dee
[docs] Update documentation on Docker containers
mcopik Dec 7, 2025
a1464e7
Revise build documentation for clarity and detail
mcopik Dec 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/000.microbenchmarks/010.sleep/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"timeout": 120,
"memory": 128,
"languages": ["python", "nodejs"],
"languages": ["python", "nodejs", "cpp"],
"modules": []
}
22 changes: 22 additions & 0 deletions benchmarks/000.microbenchmarks/010.sleep/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

#include <aws/core/Aws.h>
#include <aws/core/utils/json/JsonSerializer.h>
#include <aws/lambda-runtime/runtime.h>

#include <thread>
#include <iostream>

Aws::Utils::Json::JsonValue function(Aws::Utils::Json::JsonView json)
{
int sleep = json.GetInteger("sleep");

std::chrono::seconds timespan(sleep);
std::this_thread::sleep_for(timespan);

//std::string res_json = "{ \"result\": " + std::to_string(sleep) + "}";
//return aws::lambda_runtime::invocation_response::success(res_json, "application/json");
Aws::Utils::Json::JsonValue val;
val.WithObject("result", std::to_string(sleep));
return val;
}

73 changes: 73 additions & 0 deletions benchmarks/wrappers/aws/cpp/handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

#include <aws/core/Aws.h>
#include <aws/lambda-runtime/runtime.h>
#include <aws/s3/S3Client.h>

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "utils.hpp"

// Global variables that are retained across function invocations
bool cold_execution = true;
std::string container_id = "";
std::string cold_start_var = "";

Aws::Utils::Json::JsonValue function(Aws::Utils::Json::JsonView req);

aws::lambda_runtime::invocation_response handler(aws::lambda_runtime::invocation_request const &req)
{
Aws::Utils::Json::JsonValue json(req.payload);
Aws::Utils::Json::JsonView json_view = json.View();
// HTTP trigger with API Gateaway sends payload as a serialized JSON
// stored under key 'body' in the main JSON
// The SDK trigger converts everything for us
if(json_view.ValueExists("body")){
Aws::Utils::Json::JsonValue parsed_body{json_view.GetString("body")};
json = std::move(parsed_body);
json_view = json.View();
}

const auto begin = std::chrono::system_clock::now();
auto ret = function(json.View());
const auto end = std::chrono::system_clock::now();

Aws::Utils::Json::JsonValue body;
body.WithObject("result", ret);

// Switch cold execution after the first one.
if(cold_execution)
cold_execution = false;

auto b = std::chrono::duration_cast<std::chrono::microseconds>(begin.time_since_epoch()).count() / 1000.0 / 1000.0;
auto e = std::chrono::duration_cast<std::chrono::microseconds>(end.time_since_epoch()).count() / 1000.0 / 1000.0;
body.WithDouble("begin", b);
body.WithDouble("end", e);
body.WithDouble("results_time", e - b);
body.WithString("request_id", req.request_id);
body.WithBool("is_cold", cold_execution);
body.WithString("container_id", container_id);
body.WithString("cold_start_var", cold_start_var);

Aws::Utils::Json::JsonValue final_result;
final_result.WithObject("body", body);
return aws::lambda_runtime::invocation_response::success(final_result.View().WriteReadable(), "application/json");
}

int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);

const char * cold_var = std::getenv("cold_start");
if(cold_var)
cold_start_var = cold_var;
container_id = boost::uuids::to_string(boost::uuids::random_generator()());

aws::lambda_runtime::run_handler(handler);

Aws::ShutdownAPI(options);
return 0;
}

103 changes: 103 additions & 0 deletions benchmarks/wrappers/aws/cpp/key-value.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

#include <memory>

#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/dynamodb/model/AttributeDefinition.h>
#include <aws/dynamodb/model/GetItemRequest.h>
#include <aws/dynamodb/model/PutItemRequest.h>
#include <aws/dynamodb/model/PutItemResult.h>

#include <boost/interprocess/streams/bufferstream.hpp>

#include "key-value.hpp"
#include "utils.hpp"

KeyValue::KeyValue()
{
Aws::Client::ClientConfiguration config;
//config.region = "eu-central-1";
config.caFile = "/etc/pki/tls/certs/ca-bundle.crt";

char const TAG[] = "LAMBDA_ALLOC";
auto credentialsProvider = Aws::MakeShared<Aws::Auth::EnvironmentAWSCredentialsProvider>(TAG);
_client.reset(new Aws::DynamoDB::DynamoDBClient(credentialsProvider, config));
}

uint64_t KeyValue::download_file(Aws::String const &table, Aws::String const &key,
int &required_retries, double& read_units, bool with_backoff)
{
Aws::DynamoDB::Model::GetItemRequest req;

// Set up the request
req.SetTableName(table);
req.SetReturnConsumedCapacity(Aws::DynamoDB::Model::ReturnConsumedCapacity::TOTAL);
Aws::DynamoDB::Model::AttributeValue hashKey;
hashKey.SetS(key);
req.AddKey("key", hashKey);

auto bef = timeSinceEpochMillisec();
int retries = 0;
const int MAX_RETRIES = 1500;

while (retries < MAX_RETRIES) {
auto get_result = _client->GetItem(req);
if (get_result.IsSuccess()) {

// Reference the retrieved fields/values
auto result = get_result.GetResult();
const Aws::Map<Aws::String, Aws::DynamoDB::Model::AttributeValue>& item = result.GetItem();
if (item.size() > 0) {
uint64_t finishedTime = timeSinceEpochMillisec();

required_retries = retries;
// GetReadCapacityUnits returns 0?
read_units = result.GetConsumedCapacity().GetCapacityUnits();

return finishedTime - bef;
}

} else {
retries += 1;
if(with_backoff) {
int sleep_time = retries;
if (retries > 100) {
sleep_time = retries * 2;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
}
}
}
return 0;
}

uint64_t KeyValue::upload_file(Aws::String const &table,
Aws::String const &key,
double& write_units,
int size, unsigned char* pBuf)
{
Aws::Utils::ByteBuffer buf(pBuf, size);

Aws::DynamoDB::Model::PutItemRequest req;
req.SetTableName(table);
req.SetReturnConsumedCapacity(Aws::DynamoDB::Model::ReturnConsumedCapacity::TOTAL);

Aws::DynamoDB::Model::AttributeValue av;
av.SetB(buf);
req.AddItem("data", av);
av.SetS(key);
req.AddItem("key", av);

uint64_t bef = timeSinceEpochMillisec();
const Aws::DynamoDB::Model::PutItemOutcome put_result = _client->PutItem(req);
if (!put_result.IsSuccess()) {
std::cout << put_result.GetError().GetMessage() << std::endl;
return 1;
}
auto result = put_result.GetResult();
// GetWriteCapacityUnits returns 0?
write_units = result.GetConsumedCapacity().GetCapacityUnits();
uint64_t finishedTime = timeSinceEpochMillisec();

return finishedTime - bef;
}
31 changes: 31 additions & 0 deletions benchmarks/wrappers/aws/cpp/key-value.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#include <cstdint>
#include <string>
#include <initializer_list>
#include <memory>

#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/dynamodb/DynamoDBClient.h>

class KeyValue
{
// non-copyable, non-movable
std::shared_ptr<Aws::DynamoDB::DynamoDBClient> _client;
public:

KeyValue();

uint64_t download_file(Aws::String const &bucket,
Aws::String const &key,
int& required_retries,
double& read_units,
bool with_backoff = false);

uint64_t upload_file(Aws::String const &bucket,
Aws::String const &key,
double& write_units,
int size,
unsigned char* pBuf);

};

104 changes: 104 additions & 0 deletions benchmarks/wrappers/aws/cpp/redis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

#include <string>

#include <aws/core/Aws.h>

#include "redis.hpp"
#include "utils.hpp"

Redis::Redis(std::string redis_hostname, int redis_port)
{
_context = redisConnect(redis_hostname.c_str(), redis_port);
if (_context == nullptr || _context->err) {
if (_context) {
std::cerr << "Redis Error: " << _context->errstr << '\n';
} else {
std::cerr << "Can't allocate redis context\n";
}
}
}

bool Redis::is_initialized()
{
return _context != nullptr;
}

Redis::~Redis()
{
redisFree(_context);
}

uint64_t Redis::download_file(Aws::String const &key,
int &required_retries, bool with_backoff)
{
std::string comm = "GET " + key;

auto bef = timeSinceEpochMillisec();
int retries = 0;
const int MAX_RETRIES = 1500;

while (retries < MAX_RETRIES) {

redisReply* reply = (redisReply*) redisCommand(_context, comm.c_str());

if (reply->type == REDIS_REPLY_NIL || reply->type == REDIS_REPLY_ERROR) {

retries += 1;
if(with_backoff) {
int sleep_time = retries;
if (retries > 100) {
sleep_time = retries * 2;
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
}

} else {

uint64_t finishedTime = timeSinceEpochMillisec();
required_retries = retries;

freeReplyObject(reply);
return finishedTime - bef;

}
freeReplyObject(reply);
}
return 0;
}

uint64_t Redis::upload_file(Aws::String const &key,
int size, char* pBuf)
{
std::string comm = "SET " + key + " %b";


uint64_t bef = timeSinceEpochMillisec();
redisReply* reply = (redisReply*) redisCommand(_context, comm.c_str(), pBuf, size);
uint64_t finishedTime = timeSinceEpochMillisec();

if (reply->type == REDIS_REPLY_NIL || reply->type == REDIS_REPLY_ERROR) {
std::cerr << "Failed to write in Redis!" << std::endl;
abort();
}
freeReplyObject(reply);

return finishedTime - bef;
}

uint64_t Redis::delete_file(std::string const &key)
{
std::string comm = "DEL " + key;

uint64_t bef = timeSinceEpochMillisec();
redisReply* reply = (redisReply*) redisCommand(_context, comm.c_str());
uint64_t finishedTime = timeSinceEpochMillisec();

if (reply->type == REDIS_REPLY_NIL || reply->type == REDIS_REPLY_ERROR) {
std::cerr << "Couldn't delete the key!" << '\n';
abort();
}
freeReplyObject(reply);

return finishedTime - bef;
}

26 changes: 26 additions & 0 deletions benchmarks/wrappers/aws/cpp/redis.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

#include <cstdint>
#include <string>

#include <aws/core/utils/memory/stl/AWSString.h>

#include <hiredis/hiredis.h>

class Redis
{
redisContext* _context;
public:

Redis(std::string redis_hostname, int redis_port);
~Redis();

bool is_initialized();

uint64_t download_file(Aws::String const &key, int &required_retries, bool with_backoff);

uint64_t upload_file(Aws::String const &key, int size, char* pBuf);

uint64_t delete_file(std::string const &key);

};

Loading