Skip to content

Commit

Permalink
feat: add a benchmark to measure different performance aspects
Browse files Browse the repository at this point in the history
- benchmark can be modified to test different performance aspects of
  DRace, such as more memory accessed and less threads or more threads
  and less memory accessed
  • Loading branch information
taranbis committed Jan 15, 2021
1 parent b616a8d commit d4f6b5c
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 2 deletions.
1 change: 1 addition & 0 deletions standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ endif()
add_subdirectory("detectors/fasttrack")
add_subdirectory("binarydecoder")
add_subdirectory("helper")
add_subdirectory("ft_benchmark")
1 change: 0 additions & 1 deletion standalone/detectors/fasttrack/include/vectorclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*
* SPDX-License-Identifier: MIT
*/

#include "parallel_hashmap/phmap.h"

/**
Expand Down
2 changes: 1 addition & 1 deletion standalone/detectors/fasttrack/src/stacktrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ StackTrace::StackTree::vertex_descriptor StackTrace::get_current_element()
const {
std::lock_guard<ipc::spinlock> lg(lock);
return curr_elem;
}
}
8 changes: 8 additions & 0 deletions standalone/ft_benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set (SOURCES "ft_benchmark.cpp")

set (TARGET_NAME "ft_benchmark")

add_executable(${TARGET_NAME} ${SOURCES})

target_link_libraries(${TARGET_NAME} Threads::Threads)
set_target_properties(${TARGET_NAME} PROPERTIES CXX_STANDARD 17 CX_STANDARD_REQUIRED ON)
144 changes: 144 additions & 0 deletions standalone/ft_benchmark/ft_benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* DRace, a dynamic data race detector
*
* Copyright 2018 Siemens AG
*
* Authors:
* Felix Moessbauer <felix.moessbauer@siemens.com>
*
* SPDX-License-Identifier: MIT
*/

#include <algorithm>
#include <atomic>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <random>
#include <set>
#include <thread>
#include <vector>

std::mutex mx;
static std::set<int> random_reads;
static std::set<int> random_writes;
static std::random_device rd{};
std::mt19937 gen{ 0 };

void generate_block(int i,
std::vector<std::pair<uintptr_t*, uintptr_t*>>* blocks) {
std::mt19937_64 gen(42 + i);
uintptr_t* ptr = new uintptr_t[i];

// fill block
std::generate(ptr, ptr + i, [&]() { return gen(); });
blocks->emplace_back(ptr, ptr + i);
}

void read_from_block(std::vector<std::pair<uintptr_t*, uintptr_t*>>* blocks) {
try {
std::uniform_int_distribution<int> dist(0, blocks->size() - 1);
int rnd = dist(gen);
random_reads.emplace(rnd);
uintptr_t* begin = (*blocks)[rnd].first;
uintptr_t* end = (*blocks)[rnd].second;

uintptr_t* iter = begin;
while (iter != end) {
auto tmp = *iter;
iter++;
}
// std::this_thread::sleep_for(std::chrono::milliseconds(500));
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
} catch (...) {
std::cout << "Something!" << std::endl;
}
}

void write_to_block(std::vector<std::pair<uintptr_t*, uintptr_t*>>* blocks) {
try {
std::uniform_int_distribution<int> dist(0, blocks->size() - 1);
int rnd = dist(gen);
random_writes.emplace(rnd);
uintptr_t* begin = (*blocks)[rnd].first;
uintptr_t* end = (*blocks)[rnd].second;

uintptr_t* iter = begin;
while (iter != end) {
*iter = -1;
iter++;
}
// std::this_thread::sleep_for(std::chrono::milliseconds(500));
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
} catch (...) {
std::cout << "Something!" << std::endl;
}
}

int CountPossibleDataRaces();

/**
* Test tool to check for memory corruption and layout.
* To also check the race reporting, we try to enforce data-races
*/
int main(int argc, char** argv) {
std::vector<std::pair<uintptr_t*, uintptr_t*>> blocks;
size_t elem_allocated = 0;
{
mx.lock();
for (int i = 0; i < 32; ++i) {
for (int j = 2; j <= (32 * 1024); j *= 2) {
generate_block(j, &blocks);
elem_allocated += j;
}
}
mx.unlock();
}

auto alloc_mb = (elem_allocated * sizeof(uintptr_t)) / (1024 * 1024);
std::cout << "Allocated " << alloc_mb << " MiB" << std::endl;

int no_of_blocks = 100;
std::vector<std::thread> readers;
std::vector<std::thread> writers;

for (int i = 0; i < no_of_blocks; ++i) {
readers.emplace_back(read_from_block, &blocks);
writers.emplace_back(write_to_block, &blocks);
}

for (auto& t : readers) {
t.join();
}
for (auto& t : writers) {
t.join();
}

int no_of_data_races = CountPossibleDataRaces();

std::cout << "No. of possible data races: " << std::setw(3)
<< no_of_data_races << std::endl;
//std::cin.get();
}

int CountPossibleDataRaces() {
int result = 0;
auto it_r = random_reads.begin();
auto it_w = random_writes.begin();
while (it_r != random_reads.end() && it_w != random_writes.end()) {
if (*it_r == *it_w) {
result++; //= std::distance(blocks[*it_r].first, blocks[*it_w].second);
it_r++;
it_w++;
continue;
}
if (*it_r > *it_w) {
it_w++;
} else {
it_r++;
}
}
return result;
}

0 comments on commit d4f6b5c

Please sign in to comment.