diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c84817..aa928fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,4 +43,4 @@ target_link_libraries(memoLib ibverbs) include_directories(${CMAKE_SOURCE_DIR}/ext/memoRDMA ${CMAKE_SOURCE_DIR}/ext/memoRDMA/include) add_executable(disaggDataProvider ${SOURCES} ${HEADERS}) -target_link_libraries(disaggDataProvider "pthread" "memoLib" ${OpenMP_CXX_LIBRARIES}) \ No newline at end of file +target_link_libraries(disaggDataProvider "pthread" "memoLib" "numa" ${OpenMP_CXX_LIBRARIES}) \ No newline at end of file diff --git a/include/Benchmarks.hpp b/include/Benchmarks.hpp new file mode 100644 index 0000000..bac0942 --- /dev/null +++ b/include/Benchmarks.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Worker.hpp" + +extern std::chrono::duration waitingTime; +extern std::chrono::duration workingTime; + +class Benchmarks { + public: + static Benchmarks& getInstance() { + static Benchmarks instance; + return instance; + } + ~Benchmarks(); + + void executeAllBenchmarks(); + + static const size_t OPTIMAL_BLOCK_SIZE = 65536; + + private: + Benchmarks(); + + void execLocalBenchmark(std::string& logName, std::string locality); + void execRemoteBenchmark(std::string& logName, std::string locality); + void execLocalBenchmarkMW(std::string& logName, std::string locality); + void execRemoteBenchmarkMW(std::string& logName, std::string locality); + + template + void execUPIBenchmark(); + + void execRDMABenchmark(); + void execRDMAHashJoinBenchmark(); + void execRDMAHashJoinPGBenchmark(); + void execRDMAHashJoinStarBenchmark(); + + static const size_t WORKER_NUMBER = 8; + Worker workers[WORKER_NUMBER]; +}; diff --git a/include/Column.h b/include/Column.h index 80c70fe..32c30a6 100644 --- a/include/Column.h +++ b/include/Column.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "DataCatalog.h" @@ -40,7 +41,7 @@ struct col_t { (reinterpret_cast(data) == reinterpret_cast(col->current_end)) // Last readable element reached ) { std::unique_lock lk(col->iteratorLock); - // std::cout << "Stalling <" << (chunk_iterator ? "Chunked>" : "Full>") << std::endl; + LOG_DEBUG2("Stalling <" << (chunk_iterator ? "Chunked>" : "Full>") << std::endl;) col->iterator_data_available.wait(lk, [this] { return reinterpret_cast(data) < reinterpret_cast(col->current_end); }); } } @@ -87,7 +88,8 @@ struct col_t { std::condition_variable iterator_data_available; ~col_t() { - free(data); + // May be a problem when freeing memory not allocated with numa_alloc + numa_free(data, sizeInBytes); } template @@ -96,7 +98,16 @@ struct col_t { size = _size; data = aligned_alloc(alignof(T), _size * sizeof(T)); sizeInBytes = _size * sizeof(T); - // std::cout << "[col_t] Allocated " << _size * sizeof(T) << " bytes." << std::endl; + LOG_DEBUG2("[col_t] Allocated " << _size * sizeof(T) << " bytes." << std::endl;) + } + } + + template + void allocate_on_numa(size_t _size, int node) { + if (data == nullptr) { + size = _size; + data = numa_alloc_onnode(_size * sizeof(T), node); + sizeInBytes = _size * sizeof(T); } } @@ -136,7 +147,7 @@ struct col_t { break; } default: { - std::cout << "[col_t] Error allocating data: Invalid datatype submitted. Nothing was allocated." << std::endl; + LOG_ERROR("[col_t] Error allocating data: Invalid datatype submitted. Nothing was allocated." << std::endl;) } } @@ -144,22 +155,48 @@ struct col_t { current_end = data; } + void allocate_on_numa(col_data_t type, size_t _size, int node) { + switch (type) { + case col_data_t::gen_smallint: { + allocate_on_numa(_size, node); + break; + } + case col_data_t::gen_bigint: { + allocate_on_numa(_size, node); + break; + } + case col_data_t::gen_float: { + allocate_on_numa(_size, node); + break; + } + case col_data_t::gen_double: { + allocate_on_numa(_size, node); + break; + } + default: { + LOG_ERROR("[col_t] Error allocating data: Invalid datatype submitted. Nothing was allocated." << std::endl;) + } + } + + // memset(reinterpret_cast(data), 0, _size); + current_end = data; + } + void request_data(bool fetch_complete_column) { std::unique_lock _lk(iteratorLock); if (is_complete || requested_chunks > received_chunks) { - // std::cout << "" << std::endl; + LOG_DEBUG2("" << std::endl;) // Do Nothing, ignore. return; } ++requested_chunks; - // std::cout << "Col is requesting a new chunk." << std::endl; DataCatalog::getInstance().fetchColStub(1, ident, fetch_complete_column); } void append_chunk(size_t offset, size_t chunkSize, char* remoteData) { if (data == nullptr) { - std::cout << "!!! Implement allocation handling in append_chunk, aborting." << std::endl; + LOG_WARNING("!!! Implement allocation handling in append_chunk, aborting." << std::endl;) return; } memcpy(reinterpret_cast(data) + offset, remoteData, chunkSize); @@ -216,7 +253,7 @@ struct col_t { } default: { using namespace memordma; - Logger::getInstance() << LogLevel::ERROR << "Saw gen_void but its not handled." << std::endl; + LOG_ERROR("Saw gen_void but its not handled." << std::endl;) } } ss << " [" << (is_remote ? "remote," : "local,") << (is_complete ? "complete" : "incomplete") << "]" @@ -245,22 +282,22 @@ struct col_t { void log_to_file(std::string logfile) const { switch (datatype) { case col_data_t::gen_smallint: { - std::cout << "Printing uint8_t column" << std::endl; + LOG_DEBUG1("Printing uint8_t column" << std::endl;) log_to_file_typed(logfile); break; } case col_data_t::gen_bigint: { - std::cout << "Printing uint64_t column" << std::endl; + LOG_DEBUG1("Printing uint64_t column" << std::endl;) log_to_file_typed(logfile); break; } case col_data_t::gen_float: { - std::cout << "Printing float column" << std::endl; + LOG_DEBUG1("Printing float column" << std::endl;) log_to_file_typed(logfile); break; } case col_data_t::gen_double: { - std::cout << "Printing double column" << std::endl; + LOG_DEBUG1("Printing double column" << std::endl;) log_to_file_typed(logfile); break; } @@ -308,4 +345,123 @@ struct col_t { log << std::endl; log.close(); } +}; + +struct table_t { + public: + std::vector columns; + std::string ident; + size_t numCols; + size_t numRows; + size_t onNode; + size_t bufferRatio; + bool isFactTable; + + explicit table_t(std::string _ident, size_t _onNode) : ident{_ident}, numCols{0}, numRows{0}, onNode{_onNode}, bufferRatio{0}, isFactTable{true} {}; + + table_t(std::string _ident, size_t _numCols, size_t _numRows, size_t _onNode, size_t _bufferRatio, bool _isFactTable) : ident{_ident}, numCols{_numCols}, numRows{_numRows}, onNode{_onNode}, bufferRatio{_bufferRatio}, isFactTable{_isFactTable} { + for (size_t i = 0; i < numCols; ++i) { + columns.emplace_back(new col_t); + } + + std::default_random_engine generator; + + uint8_t colId = 0; + + for (auto& col : columns) { + col->ident = ident + "_col_" + std::to_string(colId); + col->size = numRows; + col->sizeInBytes = numRows * sizeof(uint64_t); + + if (onNode != 0) { + col->is_remote = true; + col->is_complete = false; + } else { + col->is_remote = false; + col->is_complete = true; + } + + col->datatype = col_data_t::gen_bigint; + col->data = numa_alloc_onnode(col->sizeInBytes, onNode); + + auto data = reinterpret_cast(col->data); + + if (colId == 0) { + for (size_t i = 0; i < numRows; ++i) { + data[i] = i; + } + } else { + std::uniform_int_distribution distribution; + + if (isFactTable) { + distribution = std::uniform_int_distribution(0, (numRows * bufferRatio * 0.01) - 1); + } else { + distribution = std::uniform_int_distribution(0, 100); + } + + for (size_t i = 0; i < numRows; ++i) { + data[i] = distribution(generator); + } + } + + if (col->is_complete) { + col->readableOffset = numRows * sizeof(uint64_t); + } + + col->current_end = col->data; + DataCatalog::getInstance().add_column(col->ident, col); + + ++colId; + } + } + + ~table_t() { + for (auto col : columns) { + delete col; + } + + columns.clear(); + }; + + void addColumn(uint64_t* data, size_t elementCount) { + if (numRows == 0) { + numRows = elementCount; + } else { + if (numRows != elementCount) { + LOG_ERROR("Dimension of column does not match with table!" << std::endl;) + return; + } + } + + col_t* tmp = new col_t(); + + tmp->ident = ident + "_col_" + std::to_string(numCols); + tmp->size = numRows; + tmp->sizeInBytes = numRows * sizeof(uint64_t); + + if (onNode != 0) { + tmp->is_remote = true; + tmp->is_complete = false; + } else { + tmp->is_remote = false; + tmp->is_complete = true; + } + + tmp->datatype = col_data_t::gen_bigint; + tmp->data = numa_alloc_onnode(tmp->sizeInBytes, onNode); + + std::copy(data, data + elementCount, reinterpret_cast(tmp->data)); + + if (tmp->is_complete) { + tmp->readableOffset = numRows * sizeof(uint64_t); + } + + columns.emplace_back(tmp); + + ++numCols; + } + + col_t* getPrimaryKeyColumn() { + return columns[0]; + } }; \ No newline at end of file diff --git a/include/DataCatalog.h b/include/DataCatalog.h index 22f2af0..7176130 100644 --- a/include/DataCatalog.h +++ b/include/DataCatalog.h @@ -23,7 +23,11 @@ enum class catalog_communication_code : uint8_t { receive_pseudo_pax, receive_last_pseudo_pax, reconfigure_chunk_size, - ack_reconfigure_chunk_size + ack_reconfigure_chunk_size, + generate_benchmark_data, + ack_generate_benchmark_data, + clear_catalog, + ack_clear_catalog }; enum class col_data_t : unsigned char { @@ -65,7 +69,7 @@ struct col_network_info { case col_data_t::gen_bigint: return size_info * sizeof(uint64_t); default: - std::cout << "[col_network_info] Datatype case not implemented! Column size not calculated." << std::endl; + LOG_WARNING("[col_network_info] Datatype case not implemented! Column size not calculated." << std::endl;) return 0; } } @@ -115,6 +119,7 @@ struct col_network_info { }; struct col_t; +struct table_t; struct inflight_col_info_t { col_t* col; @@ -134,7 +139,7 @@ struct pax_inflight_col_info_t { char* payload_buf = nullptr; void reset() { - std::lock_guard lk( offset_lock ); + std::lock_guard lk(offset_lock); std::queue > empty; prepared_offsets.swap(empty); if (metadata_buf) delete metadata_buf; @@ -167,13 +172,19 @@ class DataCatalog { col_remote_dict_t remote_col_info; bool col_info_received = false; bool reconfigured = false; + bool dataGenerationDone = false; + bool clearCatalogDone = false; mutable std::mutex remote_info_lock; mutable std::mutex reconfigure_lock; mutable std::mutex appendLock; mutable std::mutex inflightLock; mutable std::mutex paxInflightLock; + mutable std::mutex dataGenerationLock; + mutable std::mutex clearCatalogLock; std::condition_variable remote_info_available; std::condition_variable reconfigure_done; + std::condition_variable data_generation_done; + std::condition_variable clear_catalog_done; incomplete_transimssions_dict_t inflight_cols; incomplete_pax_transimssions_dict_t pax_inflight_cols; @@ -183,6 +194,7 @@ class DataCatalog { public: uint64_t dataCatalog_chunkMaxSize = 1024 * 512 * 4; uint64_t dataCatalog_chunkThreshold = 1024 * 512 * 4; + std::map tables; static DataCatalog& getInstance(); @@ -190,13 +202,14 @@ class DataCatalog { void operator=(DataCatalog const&) = delete; ~DataCatalog(); - void clear(); + void clear(bool sendRemot = false, bool destructor = false); void registerCallback(uint8_t code, CallbackFunction cb) const; - col_dict_t::iterator generate(std::string ident, col_data_t type, size_t elemCount); + col_dict_t::iterator generate(std::string ident, col_data_t type, size_t elemCount, int node); col_t* find_local(std::string ident) const; col_t* find_remote(std::string ident) const; + col_t* add_column(std::string ident, col_t* col); col_t* add_remote_column(std::string name, col_network_info ni); void remoteInfoReady(); @@ -205,10 +218,15 @@ class DataCatalog { void print_all() const; void print_all_remotes() const; + std::vector getLocalColumnNames() const; + std::vector getRemoteColumnNames() const; + void eraseAllRemoteColumns(); void reconfigureChunkSize(const uint64_t newChunkSize, const uint64_t newChunkThreshold); + void generateBenchmarkData(const uint64_t distinctLocalColumns, const uint64_t remoteColumnsForLocal, const uint64_t localColumnElements, const uint64_t percentageOfRemote, const uint64_t localNumaNode = 0, const uint64_t remoteNumaNode = 0, bool sendToRemote = false, bool createTables = false); + // Communication stubs void fetchColStub(std::size_t conId, std::string& ident, bool whole_column = true) const; void fetchPseudoPax(std::size_t conId, std::vector idents) const; diff --git a/include/Operators.hpp b/include/Operators.hpp new file mode 100644 index 0000000..7ab32ba --- /dev/null +++ b/include/Operators.hpp @@ -0,0 +1,155 @@ +#pragma once + +#include + +#include + +class Operators { + public: + template + static inline std::vector less_than(uint64_t* data, const uint64_t predicate, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (data[e] < predicate) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (data[e] < predicate) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector less_equal(uint64_t* data, const uint64_t predicate, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (data[e] <= predicate) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (data[e] <= predicate) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector greater_than(uint64_t* data, const uint64_t predicate, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (data[e] > predicate) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (data[e] > predicate) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector greater_equal(uint64_t* data, const uint64_t predicate, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (data[e] >= predicate) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (data[e] >= predicate) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector equal(uint64_t* data, const uint64_t predicate, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (data[e] == predicate) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (data[e] == predicate) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector between_incl(uint64_t* data, const uint64_t predicate_1, const uint64_t predicate_2, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (predicate_1 <= data[e] && data[e] <= predicate_2) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (predicate_1 <= data[e] && data[e] <= predicate_2) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } + + template + static inline std::vector between_excl(uint64_t* data, const uint64_t predicate_1, const uint64_t predicate_2, const size_t blockSize, const std::vector in_pos) { + std::vector out_vec; + out_vec.reserve(blockSize); + if (isFirst) { + for (auto e = 0; e < blockSize; ++e) { + if (predicate_1 < data[e] && data[e] < predicate_2) { + out_vec.push_back(e); + } + } + } else { + for (auto e : in_pos) { + if (predicate_1 < data[e] && data[e] < predicate_2) { + out_vec.push_back(e); + } + } + } + + return out_vec; + } +}; diff --git a/include/Queries.h b/include/Queries.h index f5090ae..4306788 100644 --- a/include/Queries.h +++ b/include/Queries.h @@ -1,5 +1,4 @@ -#ifndef QUERIES_H -#define QUERIES_H +#pragma once #include #include @@ -19,5 +18,3 @@ void executeFrontPageBenchmarkingQueries(std::string& logName); void executeLocalMTBenchmarkingQueries(std::string& logName, std::string locality); void executeRemoteMTBenchmarkingQueries(std::string& logName); - -#endif \ No newline at end of file diff --git a/include/Worker.hpp b/include/Worker.hpp new file mode 100644 index 0000000..5ae1b03 --- /dev/null +++ b/include/Worker.hpp @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +// https://codereview.stackexchange.com/questions/122075/simple-worker-class +class Worker { + public: + Worker(bool start) : m_Running(start) { + if (start) private_start(); + } + Worker() : m_Running(false) {} + ~Worker() { stop(); } + + template + void push_task(Args&&... args) { + { + std::lock_guard lk(m_Mutex); + m_Queue.push_back(std::bind(std::forward(args)...)); + } + + m_Condition.notify_all(); + } + + void start() { + { + std::lock_guard lk(m_Mutex); + if (m_Running == true) return; + m_Running = true; + } + + private_start(); + } + + void stop() { + { + std::lock_guard lk(m_Mutex); + if (m_Running == false) return; + m_Running = false; + } + + m_Condition.notify_all(); + m_Thread.join(); + } + + private: + void private_start() { + m_Thread = std::thread([this] { + for (;;) { + decltype(m_Queue) local_queue; + { + std::unique_lock lk(m_Mutex); + m_Condition.wait(lk, [&] { return !m_Queue.empty() + !m_Running; }); + + if (!m_Running) { + for (auto& func : m_Queue) + func(); + + m_Queue.clear(); + return; + } + + std::swap(m_Queue, local_queue); + } + + for (auto& func : local_queue) + func(); + } + }); + } + + private: + std::condition_variable m_Condition; + std::list> m_Queue; + std::mutex m_Mutex; + std::thread m_Thread; + bool m_Running = false; +}; \ No newline at end of file diff --git a/src/Benchmarks.cpp b/src/Benchmarks.cpp new file mode 100644 index 0000000..8fccdec --- /dev/null +++ b/src/Benchmarks.cpp @@ -0,0 +1,1987 @@ +#include "Benchmarks.hpp" + +#include +#include + +#include +#include + +#include "Operators.hpp" + +Benchmarks::Benchmarks() { + // for (auto& worker : workers) { + // worker.start(); + // } +} + +Benchmarks::~Benchmarks() {} + +std::chrono::duration waitingTime = std::chrono::duration::zero(); +std::chrono::duration workingTime = std::chrono::duration::zero(); + +inline void reset_timer() { + waitingTime = std::chrono::duration::zero(); + workingTime = std::chrono::duration::zero(); +} + +inline void wait_col_data_ready(col_t* _col, char* _data) { + auto s_ts = std::chrono::high_resolution_clock::now(); + std::unique_lock lk(_col->iteratorLock); + if (!(_data < reinterpret_cast(_col->current_end))) { + _col->iterator_data_available.wait(lk, [_col, _data] { return reinterpret_cast(_data) < reinterpret_cast(_col->current_end); }); + } + waitingTime += (std::chrono::high_resolution_clock::now() - s_ts); +} + +template +inline void fetch_data(col_t* column, uint64_t* data, const bool reload) { + if (remote) { + if (reload) { + if (!prefetching && !paxed) { + column->request_data(!chunked); + } + } + wait_col_data_ready(column, reinterpret_cast(data)); + if (reload) { + if (prefetching && chunked && !paxed) { + column->request_data(!chunked); + } + } + } +} + +template +inline std::vector less_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::less_than(data, predicate, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::less_than(data, predicate, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector less_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::less_equal(data, predicate, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::less_equal(data, predicate, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector greater_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::greater_than(data, predicate, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::greater_than(data, predicate, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector greater_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::greater_equal(data, predicate, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::greater_equal(data, predicate, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::equal(data, predicate, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::equal(data, predicate, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector between_incl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::between_incl(data, predicate_1, predicate_2, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::between_incl(data, predicate_1, predicate_2, blockSize, in_pos); + } + + return out_vec; +}; + +template +inline std::vector between_excl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { + auto data = reinterpret_cast(column->data) + offset; + + std::vector out_vec; + + fetch_data(column, data, reload); + + if (timings) { + auto s_ts = std::chrono::high_resolution_clock::now(); + out_vec = Operators::between_excl(data, predicate_1, predicate_2, blockSize, in_pos); + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + } else { + out_vec = Operators::between_excl(data, predicate_1, predicate_2, blockSize, in_pos); + } + + return out_vec; +}; + +template +uint64_t pipe_1(const uint64_t predicate, const std::vector idents) { + col_t* col_0; + col_t* col_1; + col_t* col_2; + + if (idents.size() != 3) { + LOG_ERROR("The size of 'idents' was not equal to 3" << std::endl;) + return 0; + } + + std::chrono::time_point s_ts; + + if (remote) { + col_0 = DataCatalog::getInstance().find_remote(idents[0]); + if (prefetching && !paxed) col_0->request_data(!chunked); + col_1 = DataCatalog::getInstance().find_remote(idents[1]); + if (prefetching && !paxed) col_1->request_data(!chunked); + col_2 = DataCatalog::getInstance().find_remote(idents[2]); + if (prefetching && !paxed) col_2->request_data(!chunked); + + // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); + } else { + col_0 = DataCatalog::getInstance().find_local(idents[0]); + col_1 = DataCatalog::getInstance().find_local(idents[1]); + col_2 = DataCatalog::getInstance().find_local(idents[2]); + } + + size_t columnSize = col_0->size; + + size_t max_elems_per_chunk = 0; + size_t currentBlockSize = max_elems_per_chunk; + // if (paxed) { + // size_t total_id_len = 0; + // for (auto& id : idents) { + // total_id_len += id.size(); + // } + + // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; + // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + + // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; + // currentBlockSize = max_elems_per_chunk; + // } else + if (!(remote && (chunked || paxed))) { + max_elems_per_chunk = columnSize; + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } else { + max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); + if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { + currentBlockSize = max_elems_per_chunk; + } else { + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } + } + + uint64_t sum = 0; + size_t baseOffset = 0; + size_t currentChunkElementsProcessed = 0; + + auto data_col_2 = reinterpret_cast(col_2->data); + auto data_col_0 = reinterpret_cast(col_0->data); + + while (baseOffset < columnSize) { + // if (remote && paxed) { + // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); + // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // } + + const size_t elem_diff = columnSize - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + auto le_idx = greater_than(col_2, 5, baseOffset, currentBlockSize, + less_than(col_1, 25, baseOffset, currentBlockSize, + between_incl(col_0, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), + currentChunkElementsProcessed == 0); + + s_ts = std::chrono::high_resolution_clock::now(); + for (auto idx : le_idx) { + sum += (data_col_0[idx] * data_col_2[idx]); + // ++sum; + } + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + + baseOffset += currentBlockSize; + data_col_0 += currentBlockSize; + data_col_2 += currentBlockSize; + currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; + } + + return sum; +} + +template +uint64_t pipe_2(const uint64_t predicate, const std::vector idents) { + col_t* col_0; + col_t* col_1; + col_t* col_2; + + if (idents.size() != 3) { + LOG_ERROR("The size of 'idents' was not equal to 3" << std::endl;) + return 0; + } + + std::chrono::time_point s_ts; + + if (remote) { + col_1 = DataCatalog::getInstance().find_remote(idents[1]); + if (prefetching && !paxed) col_1->request_data(!chunked); + col_0 = DataCatalog::getInstance().find_remote(idents[0]); + if (prefetching && !paxed) col_0->request_data(!chunked); + col_2 = DataCatalog::getInstance().find_remote(idents[2]); + if (prefetching && !paxed) col_2->request_data(!chunked); + + // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); + } else { + col_0 = DataCatalog::getInstance().find_local(idents[0]); + col_1 = DataCatalog::getInstance().find_local(idents[1]); + col_2 = DataCatalog::getInstance().find_local(idents[2]); + } + + size_t columnSize = col_1->size; + + size_t max_elems_per_chunk = 0; + size_t currentBlockSize = max_elems_per_chunk; + // if (paxed) { + // size_t total_id_len = 0; + // for (auto& id : idents) { + // total_id_len += id.size(); + // } + + // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; + // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + + // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; + // currentBlockSize = max_elems_per_chunk; + // } else + if (!(remote && (chunked || paxed))) { + max_elems_per_chunk = columnSize; + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } else { + max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); + if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { + currentBlockSize = max_elems_per_chunk; + } else { + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } + } + + uint64_t sum = 0; + size_t baseOffset = 0; + size_t currentChunkElementsProcessed = 0; + + auto data_col_2 = reinterpret_cast(col_2->data); + auto data_col_0 = reinterpret_cast(col_0->data); + + while (baseOffset < columnSize) { + // if (remote && paxed) { + // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); + // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // } + + const size_t elem_diff = columnSize - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + auto le_idx = less_than(col_1, predicate, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0); + + if (remote && !paxed) { + if (currentChunkElementsProcessed == 0) { + if (!prefetching && chunked) { + col_2->request_data(!chunked); + col_0->request_data(!chunked); + } + wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); + wait_col_data_ready(col_0, reinterpret_cast(data_col_0)); + if (prefetching && chunked) { + col_2->request_data(!chunked); + col_0->request_data(!chunked); + } + } + } + + s_ts = std::chrono::high_resolution_clock::now(); + for (auto idx : le_idx) { + sum += (data_col_0[idx] * data_col_2[idx]); + // ++sum; + } + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + + baseOffset += currentBlockSize; + data_col_0 += currentBlockSize; + data_col_2 += currentBlockSize; + currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; + } + + return sum; +} + +template +uint64_t pipe_3(const uint64_t predicate, const std::vector idents) { + col_t* column_0; + col_t* column_1; + col_t* column_2; + col_t* column_3; + + if (idents.size() != 4) { + LOG_ERROR("The size of 'idents' was not equal to 4" << std::endl;) + return 0; + } + + std::chrono::time_point s_ts; + + if (remote) { + column_0 = DataCatalog::getInstance().find_remote(idents[0]); + if (prefetching && !paxed) column_0->request_data(!chunked); + column_1 = DataCatalog::getInstance().find_remote(idents[1]); + if (prefetching && !paxed) column_1->request_data(!chunked); + column_2 = DataCatalog::getInstance().find_remote(idents[2]); + if (prefetching && !paxed) column_2->request_data(!chunked); + column_3 = DataCatalog::getInstance().find_remote(idents[3]); + if (prefetching && !paxed) column_3->request_data(!chunked); + + // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); + } else { + column_0 = DataCatalog::getInstance().find_local(idents[0]); + column_1 = DataCatalog::getInstance().find_local(idents[1]); + column_2 = DataCatalog::getInstance().find_local(idents[2]); + column_3 = DataCatalog::getInstance().find_local(idents[3]); + } + + size_t columnSize = column_0->size; + + size_t max_elems_per_chunk = 0; + size_t currentBlockSize = max_elems_per_chunk; + // if (paxed) { + // size_t total_id_len = 0; + // for (auto& id : idents) { + // total_id_len += id.size(); + // } + + // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; + // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + + // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; + // currentBlockSize = max_elems_per_chunk; + // } else + if (!(remote && (chunked || paxed))) { + max_elems_per_chunk = columnSize; + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } else { + max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); + if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { + currentBlockSize = max_elems_per_chunk; + } else { + currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + } + } + + uint64_t sum = 0; + size_t baseOffset = 0; + size_t currentChunkElementsProcessed = 0; + + auto data_2 = reinterpret_cast(column_2->data); + auto data_3 = reinterpret_cast(column_3->data); + + while (baseOffset < columnSize) { + // if (remote && paxed) { + // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // wait_col_data_ready(column_3, reinterpret_cast(data_3)); + // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); + // } + + const size_t elem_diff = columnSize - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + auto le_idx = equal(column_3, 16, baseOffset, currentBlockSize, + greater_than(column_2, 5, baseOffset, currentBlockSize, + less_than(column_1, 25, baseOffset, currentBlockSize, + between_incl(column_0, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), + currentChunkElementsProcessed == 0), + currentChunkElementsProcessed == 0); + + s_ts = std::chrono::high_resolution_clock::now(); + for (auto idx : le_idx) { + sum += (data_2[idx] * data_3[idx]); + // ++sum; + } + workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + + baseOffset += currentBlockSize; + data_2 += currentBlockSize; + data_3 += currentBlockSize; + currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; + } + + return sum; +} + +uint64_t pipe_4(std::string& ident) { + col_t* column_0; + + column_0 = DataCatalog::getInstance().find_local(ident); + + size_t columnSize = column_0->size; + + uint64_t sum = 0; + auto data = reinterpret_cast(column_0->data); + + for (size_t i = 0; i < columnSize; ++i) { + sum += data[i]; + } + + return sum; +} + +uint64_t pipe_5(std::string& ident) { + col_t* column_0; + + column_0 = DataCatalog::getInstance().find_local(ident); + + size_t columnSize = column_0->size; + + uint64_t cnt = 0; + auto data = reinterpret_cast(column_0->data); + + for (size_t i = 0; i < columnSize; ++i) { + if (data[i] >= 5 && data[i] <= 15) { + ++cnt; + } + } + + return cnt; +} + +uint64_t pipe_6(std::string& ident) { + col_t* column_0; + + column_0 = DataCatalog::getInstance().find_local(ident); + + size_t columnSize = column_0->size; + + uint64_t sum = 0; + size_t baseOffset = 0; + uint64_t* data = reinterpret_cast(column_0->data); + + size_t currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + + while (baseOffset < columnSize) { + const size_t elem_diff = columnSize - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + for (size_t i = 0; i < currentBlockSize; ++i, ++data) { + sum += *data; + } + + baseOffset += currentBlockSize; + } + + return sum; +} + +uint64_t pipe_7(std::string& ident) { + col_t* column_0; + + column_0 = DataCatalog::getInstance().find_remote(ident); + column_0->request_data(false); + + size_t columnSize = column_0->size; + + uint64_t sum = 0; + size_t baseOffset = 0; + + uint64_t* data = reinterpret_cast(column_0->data); + + size_t currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); + + while (baseOffset < columnSize) { + const size_t elem_diff = columnSize - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + wait_col_data_ready(column_0, reinterpret_cast(data)); + column_0->request_data(false); + + for (size_t i = 0; i < currentBlockSize; ++i, ++data) { + sum += *data; + } + + baseOffset += currentBlockSize; + } + + return sum; +} + +size_t hash_join_1(std::pair idents) { + col_t* column_0; + col_t* column_1; + + column_1 = DataCatalog::getInstance().find_remote(idents.second); + column_1->request_data(true); + + column_0 = DataCatalog::getInstance().find_local(idents.first); + + size_t columnSize0 = column_0->size; + size_t columnSize1 = column_1->size; + + std::unordered_map> hashMap; + size_t joinResult = 0; + + uint64_t* data_0 = reinterpret_cast(column_0->data); + + for (size_t i = 0; i < columnSize0; i++) { + hashMap[data_0[i]].push_back(i); + } + + uint64_t* data_1 = reinterpret_cast(column_1->data); + wait_col_data_ready(column_1, reinterpret_cast(data_1)); + + for (size_t i = 0; i < columnSize1; i++) { + auto it = hashMap.find(data_1[i]); + if (it != hashMap.end()) { + for (const auto& matchingIndex : it->second) { + ++joinResult; + } + } + } + + return joinResult; +} + +size_t hash_join_2(std::pair idents) { + col_t* column_0; + col_t* column_1; + + column_0 = DataCatalog::getInstance().find_remote(idents.first); + column_0->request_data(true); + + column_1 = DataCatalog::getInstance().find_local(idents.second); + + size_t columnSize0 = column_0->size; + size_t columnSize1 = column_1->size; + + std::unordered_map> hashMap; + size_t joinResult = 0; + + uint64_t* data_0 = reinterpret_cast(column_0->data); + wait_col_data_ready(column_0, reinterpret_cast(data_0)); + + for (size_t i = 0; i < columnSize0; i++) { + hashMap[data_0[i]].push_back(i); + } + + uint64_t* data_1 = reinterpret_cast(column_1->data); + + for (size_t i = 0; i < columnSize1; i++) { + auto it = hashMap.find(data_1[i]); + if (it != hashMap.end()) { + for (const auto& matchingIndex : it->second) { + ++joinResult; + } + } + } + + return joinResult; +} + +size_t hash_join_3(std::pair idents) { + col_t* column_0; + col_t* column_1; + + column_0 = DataCatalog::getInstance().find_local(idents.first); + column_1 = DataCatalog::getInstance().find_local(idents.second); + + size_t columnSize0 = column_0->size; + size_t columnSize1 = column_1->size; + + std::unordered_map> hashMap; + size_t joinResult = 0; + + uint64_t* data_0 = reinterpret_cast(column_0->data); + + for (size_t i = 0; i < columnSize0; i++) { + hashMap[data_0[i]].push_back(i); + } + + uint64_t* data_1 = reinterpret_cast(column_1->data); + + for (size_t i = 0; i < columnSize1; i++) { + auto it = hashMap.find(data_1[i]); + if (it != hashMap.end()) { + for (const auto& matchingIndex : it->second) { + ++joinResult; + } + } + } + + return joinResult; +} + +void hash_join_pg(std::shared_future* ready_future, const size_t tid, const size_t local_worker_count, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::pair> idents) { + col_t* column_0; + col_t* column_1; + size_t joinResult = 0; + size_t joinCount = idents.second.size(); + size_t chunkSize = DataCatalog::getInstance().dataCatalog_chunkMaxSize; + + ++(*ready_workers); + ready_future->wait(); + auto start = std::chrono::high_resolution_clock::now(); + + column_1 = DataCatalog::getInstance().find_remote(idents.second[0]); + column_1->request_data(false); + + column_0 = DataCatalog::getInstance().find_local(idents.first); + + size_t columnSize0 = column_0->size; + size_t columnSize1 = column_1->size; + + uint64_t* data_0 = reinterpret_cast(column_0->data); + uint64_t* data_1 = reinterpret_cast(column_1->data); + + for (size_t join_cnt = 0; join_cnt < joinCount; ++join_cnt) { + std::unordered_map> hashMap; + size_t currentBlockSize = chunkSize / sizeof(uint64_t); + size_t baseOffset = 0; + + while (baseOffset < columnSize1) { + const size_t elem_diff = columnSize1 - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + wait_col_data_ready(column_1, reinterpret_cast(data_1)); + column_1->request_data(false); + + for (size_t i = 0; i < currentBlockSize; ++i) { + hashMap[data_1[i]].push_back(i + baseOffset); + } + + baseOffset += currentBlockSize; + data_1 += currentBlockSize; + } + + if (join_cnt + 1 < joinCount) { + column_1 = DataCatalog::getInstance().find_remote(idents.second[join_cnt + 1]); + column_1->request_data(false); + columnSize1 = column_1->size; + data_1 = reinterpret_cast(column_1->data); + } + + for (size_t i = 0; i < columnSize0; ++i) { + auto it = hashMap.find(data_0[i]); + if (it != hashMap.end()) { + for (const auto& _ : it->second) { + ++joinResult; + } + } + } + } + + auto end = std::chrono::high_resolution_clock::now(); + out_time[tid] = std::chrono::duration_cast(end - start).count(); + result_ptr[tid] = joinResult; + if (++(*complete_workers) == local_worker_count) { + *all_done = true; + std::unique_lock lk(*done_cv_lock); + done_cv->notify_all(); + } +} + +void hash_join_pg_alt(std::shared_future* ready_future, const size_t tid, const size_t local_worker_count, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::pair> idents) { + col_t* column_0; + col_t* column_1; + size_t joinResult = 0; + size_t joinCount = idents.second.size(); + size_t chunkSize = DataCatalog::getInstance().dataCatalog_chunkMaxSize; + + ++(*ready_workers); + ready_future->wait(); + auto start = std::chrono::high_resolution_clock::now(); + + column_0 = DataCatalog::getInstance().find_remote(idents.first); + column_0->request_data(false); + + size_t columnSize0 = column_0->size; + + uint64_t* data_0 = reinterpret_cast(column_0->data); + + for (size_t join_cnt = 0; join_cnt < joinCount; ++join_cnt) { + std::unordered_map> hashMap; + size_t currentBlockSize = chunkSize / sizeof(uint64_t); + size_t baseOffset = 0; + + column_1 = DataCatalog::getInstance().find_local(idents.second[join_cnt]); + size_t columnSize1 = column_1->size; + uint64_t* data_1 = reinterpret_cast(column_1->data); + + for (size_t i = 0; i < columnSize1; ++i) { + hashMap[data_1[i]].push_back(i); + } + + if (join_cnt == 0) { + while (baseOffset < columnSize0) { + const size_t elem_diff = columnSize0 - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + wait_col_data_ready(column_0, reinterpret_cast(data_0)); + column_0->request_data(false); + + for (size_t i = 0; i < currentBlockSize; ++i) { + auto it = hashMap.find(data_0[i]); + if (it != hashMap.end()) { + for (const auto& _ : it->second) { + ++joinResult; + } + } + } + + baseOffset += currentBlockSize; + data_0 += currentBlockSize; + } + data_0 = reinterpret_cast(column_0->data); + } else { + for (size_t i = 0; i < columnSize0; ++i) { + auto it = hashMap.find(data_0[i]); + if (it != hashMap.end()) { + for (const auto& _ : it->second) { + ++joinResult; + } + } + } + } + } + + auto end = std::chrono::high_resolution_clock::now(); + out_time[tid] = std::chrono::duration_cast(end - start).count(); + result_ptr[tid] = joinResult; + if (++(*complete_workers) == local_worker_count) { + *all_done = true; + std::unique_lock lk(*done_cv_lock); + done_cv->notify_all(); + } +} + +void hash_join_kernel_star(std::shared_future* ready_future, const size_t tid, const size_t local_worker_count, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::pair> idents) { + col_t* column_0; + col_t* column_1; + size_t joinResult = 0; + size_t joinCount = idents.second.size(); + size_t chunkSize = DataCatalog::getInstance().dataCatalog_chunkMaxSize; + table_t* result = new table_t("result_" + tid, 0); + + ++(*ready_workers); + ready_future->wait(); + auto start = std::chrono::high_resolution_clock::now(); + + table_t* factTable = DataCatalog::getInstance().tables.at(idents.first); + result->addColumn(reinterpret_cast(factTable->getPrimaryKeyColumn()->data), factTable->getPrimaryKeyColumn()->size); + + auto dimensionTable = DataCatalog::getInstance().tables.at(idents.second[0]); + column_1 = DataCatalog::getInstance().find_remote(dimensionTable->getPrimaryKeyColumn()->ident); + column_1->request_data(false); + + uint64_t* interResult = reinterpret_cast(numa_alloc_onnode(factTable->numRows * sizeof(uint64_t), 0)); + + size_t columnSize1 = column_1->size; + uint64_t* data_1 = reinterpret_cast(column_1->data); + + for (size_t join_cnt = 0; join_cnt < joinCount; ++join_cnt) { + std::unordered_map> hashMap; + size_t baseOffset = 0; + size_t currentBlockSize = chunkSize / sizeof(uint64_t); + + column_0 = factTable->columns[join_cnt + 1]; + const size_t columnSize0 = column_0->size; + const uint64_t* data_0 = reinterpret_cast(column_0->data); + + while (baseOffset < columnSize1) { + const size_t elem_diff = columnSize1 - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + wait_col_data_ready(column_1, reinterpret_cast(data_1)); + column_1->request_data(false); + + for (size_t i = 0; i < currentBlockSize; ++i) { + hashMap[data_1[i]].push_back(i + baseOffset); + } + + baseOffset += currentBlockSize; + data_1 += currentBlockSize; + } + + for (size_t i = 0; i < columnSize0; ++i) { + auto it = hashMap.find(data_0[i]); + if (it != hashMap.end()) { + for (const auto& matchingIndex : it->second) { + interResult[i] = matchingIndex; + } + } + } + + if (join_cnt + 1 < joinCount) { + dimensionTable = DataCatalog::getInstance().tables.at(idents.second[join_cnt + 1]); + + column_1 = DataCatalog::getInstance().find_remote(dimensionTable->getPrimaryKeyColumn()->ident); + column_1->request_data(false); + columnSize1 = column_1->size; + data_1 = reinterpret_cast(column_1->data); + } + + result->addColumn(interResult, column_0->size); + } + + auto end = std::chrono::high_resolution_clock::now(); + out_time[tid] = std::chrono::duration_cast(end - start).count(); + result_ptr[tid] = joinResult; + if (++(*complete_workers) == local_worker_count) { + *all_done = true; + std::unique_lock lk(*done_cv_lock); + done_cv->notify_all(); + } + numa_free(interResult, factTable->numRows * sizeof(uint64_t)); + delete result; +} + +void hash_join_kernel_star_alt(std::shared_future* ready_future, const size_t tid, const size_t local_worker_count, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::pair> idents) { + col_t* column_0; + col_t* column_1; + size_t joinResult = 0; + size_t joinCount = idents.second.size(); + size_t chunkSize = DataCatalog::getInstance().dataCatalog_chunkMaxSize; + table_t* result = new table_t("result_" + tid, 0); + + ++(*ready_workers); + ready_future->wait(); + auto start = std::chrono::high_resolution_clock::now(); + + table_t* factTable = DataCatalog::getInstance().tables.at(idents.first); + result->addColumn(reinterpret_cast(factTable->getPrimaryKeyColumn()->data), factTable->getPrimaryKeyColumn()->size); + + uint64_t* interResult = reinterpret_cast(numa_alloc_onnode(factTable->numRows * sizeof(uint64_t), 0)); + + for (size_t join_cnt = 0; join_cnt < joinCount; ++join_cnt) { + std::unordered_map> hashMap; + size_t baseOffset = 0; + size_t currentBlockSize = chunkSize / sizeof(uint64_t); + + table_t* dimensionTable = DataCatalog::getInstance().tables.at(idents.second[join_cnt]); + + column_1 = dimensionTable->getPrimaryKeyColumn(); + const size_t columnSize1 = column_1->size; + uint64_t* data_1 = reinterpret_cast(column_1->data); + + column_0 = DataCatalog::getInstance().find_remote(factTable->columns[join_cnt + 1]->ident); + column_0->request_data(false); + uint64_t* data_0 = reinterpret_cast(column_0->data); + const size_t columnSize0 = column_0->size; + + for (size_t i = 0; i < columnSize1; ++i) { + hashMap[data_1[i]].push_back(i); + } + + while (baseOffset < columnSize0) { + const size_t elem_diff = columnSize0 - baseOffset; + if (elem_diff < currentBlockSize) { + currentBlockSize = elem_diff; + } + + wait_col_data_ready(column_0, reinterpret_cast(data_0)); + column_0->request_data(false); + + for (size_t i = 0; i < currentBlockSize; ++i) { + auto it = hashMap.find(data_0[i]); + if (it != hashMap.end()) { + for (const auto& matchingIndex : it->second) { + interResult[i + baseOffset] = matchingIndex; + } + } + } + + baseOffset += currentBlockSize; + data_0 += currentBlockSize; + } + result->addColumn(interResult, column_0->size); + } + + auto end = std::chrono::high_resolution_clock::now(); + out_time[tid] = std::chrono::duration_cast(end - start).count(); + result_ptr[tid] = joinResult; + if (++(*complete_workers) == local_worker_count) { + *all_done = true; + std::unique_lock lk(*done_cv_lock); + done_cv->notify_all(); + } + numa_free(interResult, factTable->numRows * sizeof(uint64_t)); + delete result; +} + +void Benchmarks::execLocalBenchmark(std::string& logName, std::string locality) { + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + const std::array predicates{0, 1, 25, 50, 75, 100}; + std::vector idents; + + if (locality == "Local") { + idents = std::vector{"col_0", "col_1", "col_2"}; + } else if (locality == "NUMA") { + idents = std::vector{"col_18", "col_19", "col_20"}; + } + + uint64_t sum = 0; + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + + for (const auto predicate : predicates) { + for (size_t i = 0; i < 20; ++i) { + reset_timer(); + + if (predicate == 0) { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_1(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } else { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_2(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } + + std::chrono::duration secs = e_ts - s_ts; + auto additional_time = secs.count() - (workingTime.count() + waitingTime.count()); + + out << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << "\t" << additional_time << std::endl;) + } + } + + out.close(); +} + +void Benchmarks::execRemoteBenchmark(std::string& logName, std::string locality) { + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + const std::array predicates{0, 1, 25, 50, 75, 100}; + std::vector idents; + + if (locality == "RemoteLocal") { + idents = std::vector{"col_0", "col_1", "col_2"}; + } else if (locality == "RemoteNUMA") { + idents = std::vector{"col_18", "col_19", "col_20"}; + } + + uint64_t sum = 0; + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + + for (const auto predicate : predicates) { + for (size_t i = 0; i < 10; ++i) { + DataCatalog::getInstance().eraseAllRemoteColumns(); + reset_timer(); + DataCatalog::getInstance().fetchRemoteInfo(); + + if (predicate == 0) { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_1(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } else { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_2(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } + + std::chrono::duration secs = e_ts - s_ts; + auto additional_time = secs.count() - (workingTime.count() + waitingTime.count()); + + out << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << "\t" << additional_time << std::endl;) + } + } + + for (uint64_t chunkSize = 1ull << 18; chunkSize <= 1ull << 27; chunkSize <<= 1) { + DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); + + for (const auto predicate : predicates) { + for (size_t i = 0; i < 10; ++i) { + DataCatalog::getInstance().eraseAllRemoteColumns(); + reset_timer(); + DataCatalog::getInstance().fetchRemoteInfo(); + + if (predicate == 0) { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_1(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } else { + s_ts = std::chrono::high_resolution_clock::now(); + sum = pipe_2(predicate, idents); + e_ts = std::chrono::high_resolution_clock::now(); + } + + std::chrono::duration secs = e_ts - s_ts; + auto additional_time = secs.count() - (workingTime.count() + waitingTime.count()); + + out << locality << "\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << "\t" << additional_time << std::endl;) + } + } + } + + out.close(); +} + +void Benchmarks::execLocalBenchmarkMW(std::string& logName, std::string locality) { + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + const std::array predicates{0, 1, 25, 50, 75, 100}; + std::vector idents; + + if (locality == "Local") { + idents = std::vector{"col_0", "col_1", "col_2"}; + } else if (locality == "NUMA") { + idents = std::vector{"col_18", "col_19", "col_20"}; + } + + Worker workers[WORKER_NUMBER]; + + for (auto& worker : workers) { + worker.start(); + } + + for (size_t i = 0; i < 10; ++i) { + std::barrier sync_point(WORKER_NUMBER * predicates.size() + 1); + + auto do_work = [&](int predicate) { + if (predicate == 0) { + pipe_1(predicate, idents); + } else { + pipe_2(predicate, idents); + } + sync_point.arrive_and_drop(); + }; + + std::chrono::_V2::system_clock::time_point s_ts = std::chrono::high_resolution_clock::now(); + for (const auto predicate : predicates) { + for (auto& worker : workers) { + worker.push_task(do_work, predicate); + } + } + + sync_point.arrive_and_wait(); + + std::chrono::_V2::system_clock::time_point e_ts = std::chrono::high_resolution_clock::now(); + + std::chrono::duration secs = e_ts - s_ts; + + out << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl;) + } + + for (auto& worker : workers) { + worker.stop(); + } + + out.close(); +} + +void Benchmarks::execRemoteBenchmarkMW(std::string& logName, std::string locality) { + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + const std::array predicates{0, 1, 25, 50, 75, 100}; + std::vector> idents; + + if (locality == "LocalRemoteLocal" || locality == "NUMARemoteLocal") { + idents = std::vector>{{"col_0", "col_1", "col_2"}, {"col_3", "col_4", "col_5"}, {"col_6", "col_7", "col_8"}, {"col_9", "col_10", "col_11"}, {"col_12", "col_13", "col_14"}, {"col_15", "col_16", "col_17"}}; + } else if (locality == "LocalRemoteNUMA" || locality == "NUMARemoteNUMA") { + idents = std::vector>{{"col_18", "col_19", "col_20"}, {"col_21", "col_22", "col_23"}, {"col_24", "col_25", "col_26"}, {"col_27", "col_28", "col_29"}, {"col_30", "col_31", "col_32"}, {"col_33", "col_34", "col_35"}}; + } + + if (locality == "NUMARemoteLocal" || locality == "NUMARemoteNUMA") { + struct bitmask* mask = numa_bitmask_alloc(numa_num_possible_nodes()); + numa_bitmask_setbit(mask, 1); + numa_run_on_node_mask(mask); + numa_bitmask_free(mask); + } else if (locality == "LocalRemoteLocal" || locality == "LocalRemoteNUMA") { + struct bitmask* mask = numa_bitmask_alloc(numa_num_possible_nodes()); + numa_bitmask_setbit(mask, 0); + numa_run_on_node_mask(mask); + numa_bitmask_free(mask); + } + + Worker workers[WORKER_NUMBER]; + + for (auto& worker : workers) { + worker.start(); + } + + for (size_t i = 0; i < 10; ++i) { + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + std::barrier sync_point(WORKER_NUMBER * predicates.size() + 1); + + auto do_work = [&](int predicate, size_t index) { + if (predicate == 0) { + pipe_1(predicate, idents[index]); + } else { + pipe_2(predicate, idents[index]); + } + sync_point.arrive_and_drop(); + }; + + size_t k = 0; + std::chrono::_V2::system_clock::time_point s_ts = std::chrono::high_resolution_clock::now(); + for (const auto predicate : predicates) { + for (auto& worker : workers) { + worker.push_task(do_work, predicate, k); + } + ++k; + } + + sync_point.arrive_and_wait(); + + std::chrono::_V2::system_clock::time_point e_ts = std::chrono::high_resolution_clock::now(); + + std::chrono::duration secs = e_ts - s_ts; + + out << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl;) + } + + for (uint64_t chunkSize = 1ull << 18; chunkSize <= 1ull << 27; chunkSize <<= 1) { + DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); + + for (size_t i = 0; i < 10; ++i) { + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + std::barrier sync_point(WORKER_NUMBER * predicates.size() + 1); + + auto do_work = [&](int predicate, size_t index) { + if (predicate == 1) { + pipe_1(predicate, idents[index]); + } else { + pipe_2(predicate, idents[index]); + } + sync_point.arrive_and_drop(); + }; + + size_t k = 0; + std::chrono::_V2::system_clock::time_point s_ts = std::chrono::high_resolution_clock::now(); + for (const auto predicate : predicates) { + for (auto& worker : workers) { + worker.push_task(do_work, predicate, k); + } + ++k; + } + + sync_point.arrive_and_wait(); + + std::chrono::_V2::system_clock::time_point e_ts = std::chrono::high_resolution_clock::now(); + + std::chrono::duration secs = e_ts - s_ts; + + out << locality << "\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl + << std::flush; + LOG_SUCCESS(std::fixed << std::setprecision(7) << locality << "\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << WORKER_NUMBER << "\t" << predicates.size() << "\t" << secs.count() << std::endl;) + } + } + + for (auto& worker : workers) { + worker.stop(); + } + + struct bitmask* mask = numa_bitmask_alloc(numa_num_possible_nodes()); + numa_bitmask_setbit(mask, 0); + numa_run_on_node_mask(mask); + numa_bitmask_free(mask); + + out.close(); +} + +double calculate_MiB_per_s(const size_t size_in_bytes, const size_t time_in_ns) { + return (static_cast(size_in_bytes) / 1024 / 1024) // B-to-MiB + / + (static_cast(time_in_ns) / 10e8); // ns-to-s +} + +double get_bandwidth(const size_t numBuffers, const size_t buffer_size_in_bytes, long* time_out_ptr, size_t offset) { + double bwd = 0.0; + for (size_t i = offset; i < numBuffers + offset; ++i) { + bwd += calculate_MiB_per_s(buffer_size_in_bytes, time_out_ptr[i]); + } + return bwd / numBuffers; +} + +template +void Benchmarks::execUPIBenchmark() { + cpu_set_t cpuset; + + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + std::stringstream logNameStream; + if (filter) { + logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "UPIBenchmark_filter.tsv"; + } else { + logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "UPIBenchmark_aggregate.tsv"; + } + std::string logName = logNameStream.str(); + + LOG_INFO("[Task] Set name: " << logName << std::endl;) + + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + std::vector idents; // = std::vector{"col_0", "col_1", "col_2", "col_3", "col_4", "col_5", "col_6", "col_7", "col_8", "col_9", "col_10", "col_11", "col_12", "col_13", "col_14", "col_15", "col_16", "col_17", "col_18", "col_19", "col_20", "col_21", "col_22", "col_23", "col_24", "col_25", "col_26", "col_27", "col_28", "col_29", "col_30", "col_31", "col_32", "col_33", "col_34", "col_35"}; + for (size_t i = 0; i < 36; ++i) { + std::stringstream nameStream; + nameStream << "col_" << i; + idents.push_back(nameStream.str()); + } + const size_t maxRuns = 100; + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + out << "local_buffer_cnt\tremote_buffer_cnt\tlocal_column_size\tremote_column_size\tlocal_bwdh\tremote_bwdh\twallclock_bwdh\n" + << std::flush; + size_t localColumnSize = DataCatalog::getInstance().find_local(idents[0])->sizeInBytes; + size_t remoteColumnSize = DataCatalog::getInstance().find_local(idents[idents.size() / 2])->sizeInBytes; + + for (size_t localBuffers = 0; localBuffers <= 16; ++localBuffers) { + for (size_t remoteBuffers = 0; remoteBuffers <= 16; ++remoteBuffers) { + if (localBuffers == 0 && remoteBuffers == 0) { + continue; + } + const size_t numWorkers = localBuffers + remoteBuffers; + + for (size_t run = 0; run < maxRuns; ++run) { + std::barrier sync_point_1(numWorkers + 1); + std::barrier sync_point_2(numWorkers + 1); + double local_bwdh = 0.0; + double remote_bwdh = 0.0; + double wallclock = 0.0; + long* time_out_ptr = reinterpret_cast(numa_alloc_onnode(numWorkers, 0)); + std::vector> localWorkers; + std::vector> remoteWorkers; + + auto do_work = [&](std::string ident, size_t index) { + sync_point_1.arrive_and_wait(); + // auto s_ts = std::chrono::high_resolution_clock::now(); + if (filter) { + pipe_5(ident); + } else { + pipe_4(ident); + } + time_out_ptr[index] = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - s_ts).count(); + sync_point_2.arrive_and_wait(); + }; + + for (size_t tid = 0; tid < localBuffers; ++tid) { + localWorkers.emplace_back(std::make_unique(do_work, idents[tid], tid)); + CPU_ZERO(&cpuset); + CPU_SET(tid, &cpuset); + int rc = pthread_setaffinity_np(localWorkers.back()->native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } + + for (size_t tid = localBuffers; tid < numWorkers; ++tid) { + remoteWorkers.emplace_back(std::make_unique(do_work, idents[tid - localBuffers + (idents.size() / 2)], tid)); + if (tid < 16) { + CPU_ZERO(&cpuset); + CPU_SET(tid, &cpuset); + } else { + CPU_ZERO(&cpuset); + CPU_SET(tid + 48, &cpuset); + } + int rc = pthread_setaffinity_np(remoteWorkers.back()->native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } + + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + + s_ts = std::chrono::high_resolution_clock::now(); + sync_point_1.arrive_and_wait(); + sync_point_2.arrive_and_wait(); + e_ts = std::chrono::high_resolution_clock::now(); + + wallclock += calculate_MiB_per_s((localColumnSize * localBuffers) + (remoteColumnSize * remoteBuffers), std::chrono::duration_cast(e_ts - s_ts).count()); + + local_bwdh += (localBuffers == 0) ? 0 : get_bandwidth(localBuffers, localColumnSize, time_out_ptr, 0); + remote_bwdh += (remoteBuffers == 0) ? 0 : get_bandwidth(remoteBuffers, remoteColumnSize, time_out_ptr, localBuffers); + + LOG_INFO("Local:\t" << localBuffers << "\tRemote:\t" << remoteBuffers << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Local aggregated bandwidth: " << local_bwdh << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Remote aggregated bandwidth: " << remote_bwdh << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Wallclock bandwidth: " << wallclock << std::endl;) + out << localBuffers << "\t" << remoteBuffers << "\t" << localColumnSize << "\t" << remoteColumnSize << "\t" << local_bwdh << "\t" << remote_bwdh << "\t" << wallclock << std::endl + << std::flush; + + std::for_each(localWorkers.begin(), localWorkers.end(), [](std::unique_ptr& t) { t->join(); }); + std::for_each(remoteWorkers.begin(), remoteWorkers.end(), [](std::unique_ptr& t) { t->join(); }); + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + } + } + } + LOG_NOFORMAT(std::endl;) + if (filter) { + LOG_INFO("UPI Benchmark Filter ended." << std::endl;) + } else { + LOG_INFO("UPI Benchmark Aggregation ended." << std::endl;) + } + + out.close(); +} + +void Benchmarks::execRDMABenchmark() { + cpu_set_t cpuset; + + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + std::stringstream logNameStream; + logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "RDMABenchmark_aggregate.tsv"; + std::string logName = logNameStream.str(); + + LOG_INFO("[Task] Set name: " << logName << std::endl;) + + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + std::vector idents; // = std::vector{"col_0", "col_1", "col_2", "col_3", "col_4", "col_5", "col_6", "col_7", "col_8", "col_9", "col_10", "col_11", "col_12", "col_13", "col_14", "col_15", "col_16", "col_17", "col_18", "col_19", "col_20", "col_21", "col_22", "col_23", "col_24", "col_25", "col_26", "col_27", "col_28", "col_29", "col_30", "col_31", "col_32", "col_33", "col_34", "col_35"}; + for (size_t i = 0; i < 36; ++i) { + std::stringstream nameStream; + nameStream << "col_" << i; + idents.push_back(nameStream.str()); + } + const size_t maxRuns = 10; + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + out << "local_buffer_cnt\tremote_buffer_cnt\tlocal_column_size\tremote_column_size\tlocal_bwdh\tremote_bwdh\twallclock_bwdh\n" + << std::flush; + size_t localColumnSize = DataCatalog::getInstance().find_local(idents[0])->sizeInBytes; + DataCatalog::getInstance().fetchRemoteInfo(); + size_t remoteColumnSize = DataCatalog::getInstance().find_remote(idents[idents.size() / 2])->sizeInBytes; + + DataCatalog::getInstance().reconfigureChunkSize(4194304, 4194304); + + for (size_t localBuffers = 0; localBuffers <= 16; ++localBuffers) { + for (size_t remoteBuffers = 0; remoteBuffers <= 16; ++remoteBuffers) { + if (localBuffers == 0 && remoteBuffers == 0) { + continue; + } + const size_t numWorkers = localBuffers + remoteBuffers; + + for (size_t run = 0; run < maxRuns; ++run) { + std::barrier sync_point_1(numWorkers + 1); + std::barrier sync_point_2(numWorkers + 1); + double local_bwdh = 0.0; + double remote_bwdh = 0.0; + double wallclock = 0.0; + long* time_out_ptr = reinterpret_cast(numa_alloc_onnode(numWorkers, 0)); + std::vector> localWorkers; + std::vector> remoteWorkers; + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + + auto do_work_local = [&](std::string ident, size_t index) { + sync_point_1.arrive_and_wait(); + pipe_6(ident); + time_out_ptr[index] = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - s_ts).count(); + sync_point_2.arrive_and_wait(); + }; + + auto do_work_remote = [&](std::string ident, size_t index) { + sync_point_1.arrive_and_wait(); + pipe_7(ident); + time_out_ptr[index] = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - s_ts).count(); + sync_point_2.arrive_and_wait(); + }; + + for (size_t tid = 0; tid < localBuffers; ++tid) { + localWorkers.emplace_back(std::make_unique(do_work_local, idents[tid], tid)); + CPU_ZERO(&cpuset); + CPU_SET(tid, &cpuset); + int rc = pthread_setaffinity_np(localWorkers.back()->native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } + + for (size_t tid = localBuffers; tid < numWorkers; ++tid) { + remoteWorkers.emplace_back(std::make_unique(do_work_remote, idents[tid - localBuffers + idents.size() / 2], tid)); + if (tid < 16) { + CPU_ZERO(&cpuset); + CPU_SET(tid, &cpuset); + } else { + CPU_ZERO(&cpuset); + CPU_SET(tid + 48, &cpuset); + } + int rc = pthread_setaffinity_np(remoteWorkers.back()->native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } + + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + + s_ts = std::chrono::high_resolution_clock::now(); + sync_point_1.arrive_and_wait(); + sync_point_2.arrive_and_wait(); + e_ts = std::chrono::high_resolution_clock::now(); + + wallclock += calculate_MiB_per_s((localColumnSize * localBuffers) + (remoteColumnSize * remoteBuffers), std::chrono::duration_cast(e_ts - s_ts).count()); + + local_bwdh += (localBuffers == 0) ? 0 : get_bandwidth(localBuffers, localColumnSize, time_out_ptr, 0); + remote_bwdh += (remoteBuffers == 0) ? 0 : get_bandwidth(remoteBuffers, remoteColumnSize, time_out_ptr, localBuffers); + + LOG_INFO("Local:\t" << localBuffers << "\tRemote:\t" << remoteBuffers << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Local per core bandwidth: " << local_bwdh << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Remote per core bandwidth: " << remote_bwdh << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Wallclock bandwidth: " << wallclock << std::endl;) + out << localBuffers << "\t" << remoteBuffers << "\t" << localColumnSize << "\t" << remoteColumnSize << "\t" << local_bwdh << "\t" << remote_bwdh << "\t" << wallclock << std::endl + << std::flush; + + std::for_each(localWorkers.begin(), localWorkers.end(), [](std::unique_ptr& t) { t->join(); }); + std::for_each(remoteWorkers.begin(), remoteWorkers.end(), [](std::unique_ptr& t) { t->join(); }); + localWorkers.clear(); + remoteWorkers.clear(); + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + } + } + } + + LOG_NOFORMAT(std::endl;) + LOG_INFO("RDMA Benchmark Aggregation ended." << std::endl;) + + out.close(); +} + +void Benchmarks::execRDMAHashJoinBenchmark() { + cpu_set_t cpuset; + + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + std::stringstream logNameStream; + logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "RDMABenchmark_hashjoin.tsv"; + std::string logName = logNameStream.str(); + + LOG_INFO("[Task] Set name: " << logName << std::endl;) + + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7) << std::endl; + std::vector idents; // = std::vector{"col_0", "col_1", "col_2", "col_3", "col_4", "col_5", "col_6", "col_7", "col_8", "col_9", "col_10", "col_11", "col_12", "col_13", "col_14", "col_15", "col_16", "col_17", "col_18", "col_19", "col_20", "col_21", "col_22", "col_23", "col_24", "col_25", "col_26", "col_27", "col_28", "col_29", "col_30", "col_31", "col_32", "col_33", "col_34", "col_35"}; + for (size_t i = 0; i < 16; ++i) { + std::string name = "col_" + std::to_string(i); + idents.push_back(name); + } + const size_t maxRuns = 10; + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + out << "mode\tlocal_buffer_cnt\tremote_buffer_count\tlarger_column_size\tsmaller_column_size\ttime\tbwdh\n" + << std::flush; + size_t largerColumnSize = DataCatalog::getInstance().find_local(idents[0])->sizeInBytes; + size_t smallerColumnSize = DataCatalog::getInstance().find_local(idents[0] + "_0")->sizeInBytes; + + // DataCatalog::getInstance().reconfigureChunkSize(1024 * 1024 * 4, 1024 * 1024 * 4); + + for (size_t bufferCount = 1; bufferCount <= 16; ++bufferCount) { + for (size_t remote_buffer_count = 1; remote_buffer_count <= 10; ++remote_buffer_count) { + for (size_t func_indicator : {1, 2, 3}) { + for (size_t run = 0; run < maxRuns; ++run) { + std::barrier sync_point_1(bufferCount + 1); + std::barrier sync_point_2(bufferCount + 1); + double bwdh = 0.0; + size_t duration = 0; + + std::vector> workers; + + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + + auto do_work = [&](std::string ident, size_t rbc, size_t func_indicator) { + size_t res = 0; + size_t (*func)(std::pair idents); + if (func_indicator == 1) { + func = hash_join_1; + } else if (func_indicator == 2) { + func = hash_join_2; + } else if (func_indicator == 3) { + func = hash_join_3; + } else { + return; + } + + sync_point_1.arrive_and_wait(); + for (size_t i = 0; i < rbc; ++i) { + std::string sub_id = ident + "_" + std::to_string(i); + res += func(std::make_pair(sub_id, ident)); + } + sync_point_2.arrive_and_wait(); + }; + + for (size_t tid = 0; tid < bufferCount; ++tid) { + workers.emplace_back(std::make_unique(do_work, idents[tid], remote_buffer_count, func_indicator)); + CPU_ZERO(&cpuset); + CPU_SET(tid, &cpuset); + int rc = pthread_setaffinity_np(workers.back()->native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } + + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + + s_ts = std::chrono::high_resolution_clock::now(); + sync_point_1.arrive_and_wait(); + sync_point_2.arrive_and_wait(); + e_ts = std::chrono::high_resolution_clock::now(); + + duration = std::chrono::duration_cast(e_ts - s_ts).count(); + + bwdh = calculate_MiB_per_s((largerColumnSize + (smallerColumnSize * remote_buffer_count)) * bufferCount, duration); + + LOG_INFO("Mode: " << func_indicator << std::endl;) + LOG_INFO("Buffer Count: " << bufferCount << std::endl;) + LOG_INFO("Join Count: " << remote_buffer_count << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Bandwidth: " << bwdh << std::endl;) + out << func_indicator << "\t" << bufferCount << "\t" << remote_buffer_count << "\t" << largerColumnSize << "\t" << smallerColumnSize << "\t" << duration << "\t" << bwdh << std::endl + << std::flush; + + std::for_each(workers.begin(), workers.end(), [](std::unique_ptr& t) { t->join(); }); + workers.clear(); + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(100ms); + } + } + } + } + } + + LOG_INFO(std::endl;) + LOG_INFO("RDMA Benchmark Hash Join ended." << std::endl;) + + out.close(); +} + +typedef std::function* ready_future, const size_t tid, const size_t local_worker_count, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::pair> idents)> BenchKernel; + +void spawn_threads(BenchKernel kernel, std::vector& pin_list, std::vector& pool, std::shared_future* ready_future, const size_t local_worker_count, const size_t join_cnt, std::atomic* ready_workers, std::atomic* complete_workers, std::condition_variable* done_cv, std::mutex* done_cv_lock, bool* all_done, uint64_t* result_ptr, long* out_time, std::string prefix) { + cpu_set_t cpuset; + for (auto pin : pin_list) { + std::vector small_tabs; + + std::string name = prefix + std::to_string(pin); + for (size_t j = 0; j < join_cnt; ++j) { + small_tabs.push_back(name + "_" + std::to_string(j)); + } + std::pair> idents = std::make_pair(name, small_tabs); + + pool.emplace_back(std::thread(kernel, ready_future, pin, local_worker_count, ready_workers, complete_workers, done_cv, done_cv_lock, all_done, result_ptr, out_time, idents)); + + CPU_ZERO(&cpuset); + CPU_SET(pin, &cpuset); + int rc = pthread_setaffinity_np(pool.back().native_handle(), sizeof(cpu_set_t), &cpuset); + if (rc != 0) { + LOG_ERROR("Error calling pthread_setaffinity_np in copy_pool assignment: " << rc << std::endl;) + exit(-10); + } + } +} + +void Benchmarks::execRDMAHashJoinPGBenchmark() { + const uint64_t numWorkers = 16; + const uint64_t maximalJoinCnt = 20; + const uint64_t localColumnElements = 1600000; + const uint64_t minBufferRatio = 10; + const uint64_t maxBufferRatio = 10; + const uint64_t localNumaNode = 0; + const uint64_t remoteNumaNode = 0; + const uint64_t maxRuns = 5; + + const std::vector global_pins = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; + + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + + for (uint64_t experimentCode : {0, 1}) { + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + std::stringstream logNameStream; + logNameStream << "results/pg_hashjoin/" << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "RDMApghashjoin_" << remoteNumaNode << "_" << std::to_string(numWorkers) << "_" << std::to_string(localColumnElements * sizeof(uint64_t)) << "_" << std::to_string(experimentCode) << ".tsv"; + std::string logName = logNameStream.str(); + + LOG_INFO("[Task] Set name: " << logName << std::endl;) + + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7); + + out << "local_buffer_cnt\tjoin_cnt\tbuffer_ratio\ttime[ns]\tbwdh\n" + << std::flush; + + std::pair kernel_pair; + + if (experimentCode == 0) { + kernel_pair = std::make_pair(hash_join_pg, "hashjoin"); + } else { + kernel_pair = std::make_pair(hash_join_pg_alt, "hashjoin"); + } + + DataCatalog::getInstance().clear(true); + + DataCatalog::getInstance().reconfigureChunkSize(1024 * 1024 * 4, 1024 * 1024 * 4); + + for (size_t bufferRatio = minBufferRatio; bufferRatio <= maxBufferRatio; bufferRatio += 5) { + LOG_INFO(" --- Running Kernel: " << kernel_pair.second << " / Buffer Ratio: " << bufferRatio << " --- " << std::endl;) + + DataCatalog::getInstance().generateBenchmarkData(numWorkers, maximalJoinCnt, localColumnElements, bufferRatio, localNumaNode, remoteNumaNode, true, false); + + const uint64_t remoteColumnElements = localColumnElements * bufferRatio * 0.01; + const uint64_t largerColumnSize = localColumnElements * sizeof(uint64_t); + const uint64_t smallerColumnSize = remoteColumnElements * sizeof(uint64_t); + + for (size_t local_buffer_cnt = 2; local_buffer_cnt <= numWorkers; local_buffer_cnt += 2) { + for (size_t join_cnt = 1; join_cnt <= maximalJoinCnt; ++join_cnt) { + for (size_t runs = 0; runs < maxRuns; ++runs) { + reset_timer(); + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + + std::atomic ready_workers = {0}; + std::atomic complete_workers = {0}; + std::condition_variable done_cv; + std::mutex done_cv_lock; + bool all_done = false; + + std::vector worker_pool; + + std::promise p; + std::shared_future ready_future(p.get_future()); + + const size_t res_ptr_size = sizeof(uint64_t) * local_buffer_cnt; + const size_t time_out_ptr_size = sizeof(long) * local_buffer_cnt; + uint64_t* result_out_ptr = reinterpret_cast(numa_alloc_onnode(res_ptr_size, 0)); + long* time_out_ptr = reinterpret_cast(numa_alloc_onnode(time_out_ptr_size, 0)); + + std::vector local_pin_list; + + for (size_t i = 0; i < local_buffer_cnt; ++i) { + local_pin_list.emplace_back(global_pins[i]); + } + + LOG_INFO("---" << std::endl;) + + spawn_threads(kernel_pair.first, local_pin_list, worker_pool, &ready_future, local_buffer_cnt, join_cnt, &ready_workers, &complete_workers, &done_cv, &done_cv_lock, &all_done, result_out_ptr, time_out_ptr, "col_"); + + { + using namespace std::chrono_literals; + while (ready_workers != local_buffer_cnt) { + std::this_thread::sleep_for(1ms); + } + } + + auto start = std::chrono::high_resolution_clock::now(); + p.set_value(); + + { + std::unique_lock lk(done_cv_lock); + done_cv.wait(lk, [&all_done] { return all_done; }); + } + + auto end = std::chrono::high_resolution_clock::now(); + const size_t duration = std::chrono::duration_cast(end - start).count(); + const double wallclock_bwdh = calculate_MiB_per_s(((largerColumnSize + smallerColumnSize) * join_cnt) * local_buffer_cnt, duration); + + std::for_each(worker_pool.begin(), worker_pool.end(), [](std::thread& t) { t.join(); }); + worker_pool.clear(); + + numa_free(result_out_ptr, res_ptr_size); + numa_free(time_out_ptr, time_out_ptr_size); + + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Wallclock bandwidth: " << wallclock_bwdh << std::endl;) + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Waiting time total: " << std::chrono::duration_cast(waitingTime).count() << "\tWaiting per thread " << std::chrono::duration_cast(waitingTime).count() / local_buffer_cnt << std::endl;) + out << std::to_string(local_buffer_cnt) << "\t" << std::to_string(join_cnt) << "\t" << std::to_string(bufferRatio) << "\t" << std::to_string(duration) << "\t" << wallclock_bwdh << std::endl + << std::flush; + } + } + } + DataCatalog::getInstance().clear(true); + } + + LOG_NOFORMAT(std::endl;) + LOG_INFO("RDMA Benchmark Hash Join PG ended." << std::endl;) + + out.close(); + } +} + +void Benchmarks::execRDMAHashJoinStarBenchmark() { + const uint64_t numWorkers = 16; + const uint64_t maximalJoinCnt = 20; + const uint64_t localColumnElements = 1600000; + const uint64_t minBufferRatio = 5; + const uint64_t maxBufferRatio = 5; + const uint64_t localNumaNode = 0; + const uint64_t remoteNumaNode = 0; + const uint64_t maxRuns = 5; + + const std::vector global_pins = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; + + std::chrono::_V2::system_clock::time_point s_ts; + std::chrono::_V2::system_clock::time_point e_ts; + + for (uint64_t experimentCode : {0, 1}) { + auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + std::stringstream logNameStream; + logNameStream << "results/star/" << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "RDMAstar_" << remoteNumaNode << "_" << std::to_string(numWorkers) << "_" << std::to_string(localColumnElements * sizeof(uint64_t)) << "_" << std::to_string(experimentCode) << ".tsv"; + std::string logName = logNameStream.str(); + + LOG_INFO("[Task] Set name: " << logName << std::endl;) + + std::ofstream out; + out.open(logName, std::ios_base::app); + out << std::fixed << std::setprecision(7); + out << "local_buffer_cnt\tjoin_cnt\tbuffer_ratio\ttime[ns]\tbwdh\n" + << std::flush; + + std::pair kernel_pair; + + if (experimentCode == 0) { + kernel_pair = std::make_pair(hash_join_kernel_star, "star_hashjoin"); + } else { + kernel_pair = std::make_pair(hash_join_kernel_star_alt, "star_hashjoin"); + } + + DataCatalog::getInstance().clear(true); + + DataCatalog::getInstance().reconfigureChunkSize(1024 * 1024 * 4, 1024 * 1024 * 4); + + for (size_t bufferRatio = minBufferRatio; bufferRatio <= maxBufferRatio; bufferRatio += 5) { + LOG_INFO(" --- Running Kernel: " << kernel_pair.second << " / Buffer Ratio: " << bufferRatio << " --- " << std::endl;) + + DataCatalog::getInstance().generateBenchmarkData(numWorkers, maximalJoinCnt, localColumnElements, bufferRatio, localNumaNode, remoteNumaNode, true, true); + + const uint64_t remoteColumnElements = localColumnElements * bufferRatio * 0.01; + const uint64_t largerColumnSize = localColumnElements * sizeof(uint64_t); + const uint64_t smallerColumnSize = remoteColumnElements * sizeof(uint64_t); + + for (size_t local_buffer_cnt = 2; local_buffer_cnt <= numWorkers; local_buffer_cnt += 2) { + for (size_t join_cnt = 1; join_cnt <= maximalJoinCnt; ++join_cnt) { + for (size_t runs = 0; runs < maxRuns; ++runs) { + DataCatalog::getInstance().eraseAllRemoteColumns(); + DataCatalog::getInstance().fetchRemoteInfo(); + + std::atomic ready_workers = {0}; + std::atomic complete_workers = {0}; + std::condition_variable done_cv; + std::mutex done_cv_lock; + bool all_done = false; + + std::vector worker_pool; + + std::promise p; + std::shared_future ready_future(p.get_future()); + + const size_t res_ptr_size = sizeof(uint64_t) * local_buffer_cnt; + const size_t time_out_ptr_size = sizeof(long) * local_buffer_cnt; + uint64_t* result_out_ptr = reinterpret_cast(numa_alloc_onnode(res_ptr_size, 0)); + long* time_out_ptr = reinterpret_cast(numa_alloc_onnode(time_out_ptr_size, 0)); + + std::vector local_pin_list; + + for (size_t i = 0; i < local_buffer_cnt; ++i) { + local_pin_list.emplace_back(global_pins[i]); + } + + LOG_INFO("---" << std::endl;) + + spawn_threads(kernel_pair.first, local_pin_list, worker_pool, &ready_future, local_buffer_cnt, join_cnt, &ready_workers, &complete_workers, &done_cv, &done_cv_lock, &all_done, result_out_ptr, time_out_ptr, "tab_"); + + { + using namespace std::chrono_literals; + while (ready_workers != local_buffer_cnt) { + std::this_thread::sleep_for(1ms); + } + } + + auto start = std::chrono::high_resolution_clock::now(); + p.set_value(); + + { + std::unique_lock lk(done_cv_lock); + done_cv.wait(lk, [&all_done] { return all_done; }); + } + + auto end = std::chrono::high_resolution_clock::now(); + const size_t duration = std::chrono::duration_cast(end - start).count(); + const double wallclock_bwdh = calculate_MiB_per_s(((largerColumnSize + smallerColumnSize) * join_cnt) * local_buffer_cnt, duration); + + std::for_each(worker_pool.begin(), worker_pool.end(), [](std::thread& t) { t.join(); }); + worker_pool.clear(); + + numa_free(result_out_ptr, res_ptr_size); + numa_free(time_out_ptr, time_out_ptr_size); + + LOG_SUCCESS(std::fixed << std::setprecision(7) << "Wallclock bandwidth: " << wallclock_bwdh << std::endl;) + out << std::to_string(local_buffer_cnt) << "\t" << std::to_string(join_cnt) << "\t" << std::to_string(bufferRatio) << "\t" << std::to_string(duration) << "\t" << wallclock_bwdh << std::endl + << std::flush; + } + } + } + DataCatalog::getInstance().clear(true); + } + LOG_NOFORMAT(std::endl;) + LOG_INFO("RDMA Benchmark Hash Join Star ended." << std::endl;) + + out.close(); + } +} + +void Benchmarks::executeAllBenchmarks() { + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStreamSW; + // logNameStreamSW << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "AllBenchmarks_SW.log"; + // std::string logNameSW = logNameStreamSW.str(); + + // LOG_INFO("[Task] Set name: " << logNameSW << std::endl;) + + // execLocalBenchmark(logNameSW, "Local"); + // execLocalBenchmark(logNameSW, "NUMA"); + // execRemoteBenchmark(logNameSW, "RemoteLocal"); + // execRemoteBenchmark(logNameSW, "RemoteNUMA"); + + // LOG_NOFORMAT(std::endl;) + // LOG_INFO("Single Worker (SW) Benchmarks ended." << std::endl;) + + // in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStreamMW; + // logNameStreamMW << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "AllBenchmarks_MW.log"; + // std::string logNameMW = logNameStreamMW.str(); + + // LOG_INFO("[Task] Set name: " << logNameMW << std::endl;) + + // execLocalBenchmarkMW(logNameMW, "Local"); + // execLocalBenchmarkMW(logNameMW, "NUMA"); + // execRemoteBenchmarkMW(logNameMW, "LocalRemoteLocal"); + // execRemoteBenchmarkMW(logNameMW, "LocalRemoteNUMA"); + // execRemoteBenchmarkMW(logNameMW, "NUMARemoteLocal"); + // execRemoteBenchmarkMW(logNameMW, "NUMARemoteNUMA"); + + // LOG_NOFORMAT(std::endl;) + // LOG_INFO("Multiple Worker (MW) Benchmarks ended." << std::endl;) + + // execUPIBenchmark(); + // execUPIBenchmark(); + + // execRDMABenchmark(); + + // execRDMAHashJoinBenchmark(); + + execRDMAHashJoinPGBenchmark(); + // execRDMAHashJoinStarBenchmark(); +} \ No newline at end of file diff --git a/src/DataCatalog.cpp b/src/DataCatalog.cpp index b248be3..cf01323 100644 --- a/src/DataCatalog.cpp +++ b/src/DataCatalog.cpp @@ -7,25 +7,27 @@ #include +#include "Benchmarks.hpp" +#include "Worker.hpp" + +using namespace memordma; + DataCatalog::DataCatalog() { auto createColLambda = [this]() -> void { - std::cout << "[DataCatalog]"; - std::size_t elemCnt; char dataType; std::string ident; - bool correct; std::string input; - std::cout << " Which datatype? uint8_t [s] uint64_t [l] float [f] double [d]" << std::endl; + LOG_CONSOLE("[DataCatalog] Which datatype? uint8_t [s] uint64_t [l] float [f] double [d]" << std::endl;) std::cin >> dataType; std::cin.clear(); std::cin.ignore(10000, '\n'); - std::cout << "How many data elements?" << std::endl; + LOG_CONSOLE("How many data elements?" << std::endl;) std::cin >> elemCnt; std::cin.clear(); std::cin.ignore(10000, '\n'); - std::cout << "Column name" << std::endl; + LOG_CONSOLE("Column name" << std::endl;) std::cin >> ident; std::cin.clear(); std::cin.ignore(10000, '\n'); @@ -49,16 +51,16 @@ DataCatalog::DataCatalog() { break; } default: { - std::cout << "Incorrect datatype, aborting." << std::endl; + LOG_ERROR("Incorrect datatype, aborting." << std::endl;) return; } } - this->generate(ident, type, elemCnt); + this->generate(ident, type, elemCnt, 0); }; auto printColLambda = [this]() -> void { - std::cout << "Print info for [1] local [2] remote" << std::endl; + LOG_CONSOLE("Print info for [1] local [2] remote" << std::endl;) size_t locality; std::cin >> locality; std::cin.clear(); @@ -77,28 +79,28 @@ DataCatalog::DataCatalog() { break; } default: { - std::cout << "[DataCatalog] No valid value selected, aborting." << std::endl; + LOG_WARNING("[DataCatalog] No valid value selected, aborting." << std::endl;) return; } } std::string ident; - std::cout << "Which column?" << std::endl; + LOG_CONSOLE("Which column?" << std::endl;) std::cin >> ident; std::cin.clear(); std::cin.ignore(10000, '\n'); auto col_it = dict.find(ident); if (col_it != dict.end()) { - std::cout << col_it->second->print_data_head() << std::endl; + LOG_INFO(col_it->second->print_data_head() << std::endl;) } else { - std::cout << "[DataCatalog] Invalid column name." << std::endl; + LOG_WARNING("[DataCatalog] Invalid column name." << std::endl;) } }; auto iteratorTestLambda = [this]() -> void { fetchRemoteInfo(); - std::cout << "Print info for [1] local [2] remote" << std::endl; + LOG_CONSOLE("Print info for [1] local [2] remote" << std::endl;) size_t locality; std::cin >> locality; std::cin.clear(); @@ -117,13 +119,13 @@ DataCatalog::DataCatalog() { break; } default: { - std::cout << "[DataCatalog] No valid value selected, aborting." << std::endl; + LOG_WARNING("[DataCatalog] No valid value selected, aborting." << std::endl;) return; } } std::string ident; - std::cout << "Which column?" << std::endl; + LOG_CONSOLE("Which column?" << std::endl;) std::cin >> ident; std::cin.clear(); std::cin.ignore(10000, '\n'); @@ -138,13 +140,13 @@ DataCatalog::DataCatalog() { cur_col->request_data(true); auto cur_end = cur_col->end(); auto it = cur_col->begin(); - std::cout << "Starting..." << std::endl; + LOG_DEBUG1("Starting..." << std::endl;) for (; it != cur_end; ++it) { count += *it; } auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "(Full) I found " << count << " CS (" << cur_col->calc_checksum() << ") in " << static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 << "ms" << std::endl; - std::cout << "\t" << (static_cast(cur_col->sizeInBytes) / 1024 / 1024 / 1024) / (static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 / 1000) << "GB/s" << std::endl; + LOG_SUCCESS("(Full) I found " << count << " CS (" << cur_col->calc_checksum() << ") in " << static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 << "ms" << std::endl;) + LOG_SUCCESS("\t" << (static_cast(cur_col->sizeInBytes) / 1024 / 1024 / 1024) / (static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 / 1000) << "GB/s" << std::endl;) } eraseAllRemoteColumns(); fetchRemoteInfo(); @@ -155,19 +157,19 @@ DataCatalog::DataCatalog() { cur_col->request_data(false); auto cur_end = cur_col->end(); auto it = cur_col->begin(); - std::cout << "Starting..." << std::endl; + LOG_DEBUG1("Starting..." << std::endl;) for (; it != cur_end; ++it) { count += *it; } auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "(Chunked) I found " << count << " CS (" << cur_col->calc_checksum() << ") in " << static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 << "ms" << std::endl; - std::cout << "\t" << (static_cast(cur_col->sizeInBytes) / 1024 / 1024 / 1024) / (static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 / 1000) << "GB/s" << std::endl; + LOG_SUCCESS("(Chunked) I found " << count << " CS (" << cur_col->calc_checksum() << ") in " << static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 << "ms" << std::endl;) + LOG_SUCCESS("\t" << (static_cast(cur_col->sizeInBytes) / 1024 / 1024 / 1024) / (static_cast(std::chrono::duration_cast(t_end - t_start).count()) / 1000 / 1000) << "GB/s" << std::endl;) } eraseAllRemoteColumns(); fetchRemoteInfo(); } } else { - std::cout << "[DataCatalog] Invalid column name." << std::endl; + LOG_WARNING("[DataCatalog] Invalid column name." << std::endl;) } }; @@ -176,7 +178,7 @@ DataCatalog::DataCatalog() { }; auto logLambda = [this]() -> void { - std::cout << "Print info for [1] local [2] remote" << std::endl; + LOG_CONSOLE("Print info for [1] local [2] remote" << std::endl;) size_t locality; std::cin >> locality; std::cin.clear(); @@ -195,13 +197,13 @@ DataCatalog::DataCatalog() { break; } default: { - std::cout << "[DataCatalog] No valid value selected, aborting." << std::endl; + LOG_WARNING("[DataCatalog] No valid value selected, aborting." << std::endl;) return; } } std::string ident; - std::cout << "Which column?" << std::endl; + LOG_CONSOLE("Which column?" << std::endl;) std::cin >> ident; std::cin.clear(); std::cin.ignore(10000, '\n'); @@ -211,211 +213,206 @@ DataCatalog::DataCatalog() { std::string s(col_it->first + ".log"); col_it->second->log_to_file(s); } else { - std::cout << "[DataCatalog] Invalid column name." << std::endl; - } - }; - - auto pseudoPaxLambda = [this]() -> void { - col_t* ld = find_remote("lo_orderdate"); - - if (ld == nullptr) { - fetchRemoteInfo(); + LOG_WARNING("[DataCatalog] Invalid column name." << std::endl;) } - - ld = find_remote("lo_orderdate"); - col_t* lq = find_remote("lo_quantity"); - col_t* le = find_remote("lo_extendedprice"); - - std::cout << "[DataCatalog] Fetching PseudoPAX for lo_orderdate, lo_quantity, lo_extendedprice" << std::endl; - fetchPseudoPax(1, {"lo_orderdate", "lo_quantity", "lo_extendedprice"}); }; - auto benchQueriesRemote = [this]() -> void { - using namespace std::chrono_literals; - - for (uint8_t num_rb = 2; num_rb <= 2; ++num_rb) { - for (uint64_t bytes = 1ull << 18; bytes <= 1ull << 20; bytes <<= 1) { - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB_" << +num_rb << "_" << +bytes << "_Remote.log"; - std::string logName = logNameStream.str(); - - std::cout << "[Task] Set name: " << logName << std::endl; - - buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, - .num_own_receive_threads = num_rb, - .num_remote_send_threads = num_rb, - .num_remote_receive_threads = num_rb, - .num_own_receive = num_rb, - .size_own_receive = bytes, - .num_remote_receive = num_rb, - .size_remote_receive = bytes, - .num_own_send = num_rb, - .size_own_send = bytes, - .num_remote_send = num_rb, - .size_remote_send = bytes, - .meta_info_size = 16}; - - ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); - - using namespace std::chrono_literals; - std::this_thread::sleep_for(2s); - - std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; - std::cout << std::endl; - - executeRemoteBenchmarkingQueries(logName); - } + // auto pseudoPaxLambda = [this]() -> void { + // col_t* ld = find_remote("lo_orderdate"); - std::cout << std::endl; - std::cout << "QueryBench ended." << std::endl; - } - }; - - auto benchQueriesLocal = [this]() -> void { - using namespace std::chrono_literals; - - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "Local.log"; - std::string logName = logNameStream.str(); - - std::cout << "[Task] Set name: " << logName << std::endl; - - executeLocalBenchmarkingQueries(logName, "Local"); + // if (ld == nullptr) { + // fetchRemoteInfo(); + // } - std::cout << std::endl; - std::cout << "NUMAQueryBench ended." << std::endl; - }; + // ld = find_remote("lo_orderdate"); + // col_t* lq = find_remote("lo_quantity"); + // col_t* le = find_remote("lo_extendedprice"); - auto benchQueriesNUMA = [this]() -> void { - using namespace std::chrono_literals; + // std::cout << "[DataCatalog] Fetching PseudoPAX for lo_orderdate, lo_quantity, lo_extendedprice" << std::endl; + // fetchPseudoPax(1, {"lo_orderdate", "lo_quantity", "lo_extendedprice"}); + // }; - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "NUMA.log"; - std::string logName = logNameStream.str(); + // auto benchQueriesRemote = [this]() -> void { + // using namespace std::chrono_literals; - std::cout << "[Task] Set name: " << logName << std::endl; + // for (uint8_t num_rb = 2; num_rb <= 2; ++num_rb) { + // for (uint64_t bytes = 1ull << 18; bytes <= 1ull << 20; bytes <<= 1) { + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB_" << +num_rb << "_" << +bytes << "_Remote.log"; + // std::string logName = logNameStream.str(); + + // std::cout << "[Task] Set name: " << logName << std::endl; + + // buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, + // .num_own_receive_threads = num_rb, + // .num_remote_send_threads = num_rb, + // .num_remote_receive_threads = num_rb, + // .num_own_receive = num_rb, + // .size_own_receive = bytes, + // .num_remote_receive = num_rb, + // .size_remote_receive = bytes, + // .num_own_send = num_rb, + // .size_own_send = bytes, + // .num_remote_send = num_rb, + // .size_remote_send = bytes, + // .meta_info_size = 16}; + + // ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); + + // std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; + // std::cout << std::endl; + + // executeRemoteBenchmarkingQueries(logName); + // } + + // std::cout << std::endl; + // std::cout << "QueryBench ended." << std::endl; + // } + // }; - executeLocalBenchmarkingQueries(logName, "NUMA"); + // auto benchQueriesLocal = [this]() -> void { + // using namespace std::chrono_literals; - std::cout << std::endl; - std::cout << "NUMAQueryBench ended." << std::endl; - }; + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "Local.log"; + // std::string logName = logNameStream.str(); - auto benchQueriesFrontPage = [this]() -> void { - using namespace std::chrono_literals; - uint8_t num_rb = 2; - uint64_t bytes = 1ull << 19; + // std::cout << "[Task] Set name: " << logName << std::endl; - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "FP_" << +num_rb << "_" << +bytes << "_Remote.log"; - std::string logName = logNameStream.str(); + // executeLocalBenchmarkingQueries(logName, "Local"); - std::cout << "[Task] Set name: " << logName << std::endl; + // std::cout << std::endl; + // std::cout << "NUMAQueryBench ended." << std::endl; + // }; - buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, - .num_own_receive_threads = num_rb, - .num_remote_send_threads = num_rb, - .num_remote_receive_threads = num_rb, - .num_own_receive = num_rb, - .size_own_receive = bytes, - .num_remote_receive = num_rb, - .size_remote_receive = bytes, - .num_own_send = num_rb, - .size_own_send = bytes, - .num_remote_send = num_rb, - .size_remote_send = bytes, - .meta_info_size = 16}; + // auto benchQueriesNUMA = [this]() -> void { + // using namespace std::chrono_literals; - ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "NUMA.log"; + // std::string logName = logNameStream.str(); - using namespace std::chrono_literals; - std::this_thread::sleep_for(2s); + // std::cout << "[Task] Set name: " << logName << std::endl; - std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; - std::cout << std::endl; + // executeLocalBenchmarkingQueries(logName, "NUMA"); - executeFrontPageBenchmarkingQueries(logName); + // std::cout << std::endl; + // std::cout << "NUMAQueryBench ended." << std::endl; + // }; - std::cout << std::endl; - std::cout << "QueryBench ended." << std::endl; - }; + // auto benchQueriesFrontPage = [this]() -> void { + // using namespace std::chrono_literals; + // uint8_t num_rb = 2; + // uint64_t bytes = 1ull << 19; + + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "FP_" << +num_rb << "_" << +bytes << "_Remote.log"; + // std::string logName = logNameStream.str(); + + // std::cout << "[Task] Set name: " << logName << std::endl; + + // buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, + // .num_own_receive_threads = num_rb, + // .num_remote_send_threads = num_rb, + // .num_remote_receive_threads = num_rb, + // .num_own_receive = num_rb, + // .size_own_receive = bytes, + // .num_remote_receive = num_rb, + // .size_remote_receive = bytes, + // .num_own_send = num_rb, + // .size_own_send = bytes, + // .num_remote_send = num_rb, + // .size_remote_send = bytes, + // .meta_info_size = 16}; + + // ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); + + // std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; + // std::cout << std::endl; + + // executeFrontPageBenchmarkingQueries(logName); + + // std::cout << std::endl; + // std::cout << "QueryBench ended." << std::endl; + // }; + + // auto benchQueriesRemoteMT = [this]() -> void { + // using namespace std::chrono_literals; - auto benchQueriesRemoteMT = [this]() -> void { - using namespace std::chrono_literals; - - for (uint8_t num_rb = 2; num_rb <= 2; ++num_rb) { - for (uint64_t bytes = 1ull << 18; bytes <= 1ull << 20; bytes <<= 1) { - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_" << +num_rb << "_" << +bytes << "_Remote.log"; - std::string logName = logNameStream.str(); - - std::cout << "[Task] Set name: " << logName << std::endl; - - buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, - .num_own_receive_threads = num_rb, - .num_remote_send_threads = num_rb, - .num_remote_receive_threads = num_rb, - .num_own_receive = num_rb, - .size_own_receive = bytes, - .num_remote_receive = num_rb, - .size_remote_receive = bytes, - .num_own_send = num_rb, - .size_own_send = bytes, - .num_remote_send = num_rb, - .size_remote_send = bytes, - .meta_info_size = 16}; - - ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); - - using namespace std::chrono_literals; - std::this_thread::sleep_for(2s); - - std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; - std::cout << std::endl; - - executeRemoteMTBenchmarkingQueries(logName); - } + // for (uint8_t num_rb = 2; num_rb <= 2; ++num_rb) { + // for (uint64_t bytes = 1ull << 18; bytes <= 1ull << 20; bytes <<= 1) { + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_" << +num_rb << "_" << +bytes << "_Remote.log"; + // std::string logName = logNameStream.str(); + + // std::cout << "[Task] Set name: " << logName << std::endl; + + // buffer_config_t bufferConfig = {.num_own_send_threads = num_rb, + // .num_own_receive_threads = num_rb, + // .num_remote_send_threads = num_rb, + // .num_remote_receive_threads = num_rb, + // .num_own_receive = num_rb, + // .size_own_receive = bytes, + // .num_remote_receive = num_rb, + // .size_remote_receive = bytes, + // .num_own_send = num_rb, + // .size_own_send = bytes, + // .num_remote_send = num_rb, + // .size_remote_send = bytes, + // .meta_info_size = 16}; + + // ConnectionManager::getInstance().reconfigureBuffer(1, bufferConfig); + + // std::cout << "[main] Used connection with id '1' and " << +num_rb << " remote receive buffer (size for one remote receive: " << memordma::Utility::GetBytesReadable(bytes) << ")" << std::endl; + // std::cout << std::endl; + + // executeRemoteMTBenchmarkingQueries(logName); + // } + + // std::cout << std::endl; + // std::cout << "QueryBench ended." << std::endl; + // } + // }; - std::cout << std::endl; - std::cout << "QueryBench ended." << std::endl; - } - }; + // auto benchQueriesLocalMT = [this]() -> void { + // using namespace std::chrono_literals; - auto benchQueriesLocalMT = [this]() -> void { - using namespace std::chrono_literals; + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_Local.log"; + // std::string logName = logNameStream.str(); - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_Local.log"; - std::string logName = logNameStream.str(); + // std::cout << "[Task] Set name: " << logName << std::endl; - std::cout << "[Task] Set name: " << logName << std::endl; + // executeLocalMTBenchmarkingQueries(logName, "Local"); - executeLocalMTBenchmarkingQueries(logName, "Local"); + // std::cout << std::endl; + // std::cout << "NUMAQueryBench ended." << std::endl; + // }; - std::cout << std::endl; - std::cout << "NUMAQueryBench ended." << std::endl; - }; + // auto benchQueriesNUMAMT = [this]() -> void { + // using namespace std::chrono_literals; - auto benchQueriesNUMAMT = [this]() -> void { - using namespace std::chrono_literals; + // auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // std::stringstream logNameStream; + // logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_NUMA.log"; + // std::string logName = logNameStream.str(); - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream logNameStream; - logNameStream << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d-%H-%M-%S_") << "QB-MT_NUMA.log"; - std::string logName = logNameStream.str(); + // std::cout << "[Task] Set name: " << logName << std::endl; - std::cout << "[Task] Set name: " << logName << std::endl; + // executeLocalMTBenchmarkingQueries(logName, "NUMA"); - executeLocalMTBenchmarkingQueries(logName, "NUMA"); + // std::cout << std::endl; + // std::cout << "NUMAQueryBench ended." << std::endl; + // }; - std::cout << std::endl; - std::cout << "NUMAQueryBench ended." << std::endl; + auto benchmarksAllLambda = [this]() -> void { + Benchmarks::getInstance().executeAllBenchmarks(); }; TaskManager::getInstance().registerTask(std::make_shared("createColumn", "[DataCatalog] Create new column", createColLambda)); @@ -423,15 +420,16 @@ DataCatalog::DataCatalog() { TaskManager::getInstance().registerTask(std::make_shared("printColHead", "[DataCatalog] Print first 10 values of column", printColLambda)); TaskManager::getInstance().registerTask(std::make_shared("retrieveRemoteCols", "[DataCatalog] Ask for remote columns", retrieveRemoteColsLambda)); TaskManager::getInstance().registerTask(std::make_shared("logColumn", "[DataCatalog] Log a column to file", logLambda)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkRemote", "[DataCatalog] Execute Single Pipeline Remote", benchQueriesRemote)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkLocal", "[DataCatalog] Execute Single Pipeline Local", benchQueriesLocal)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkNUMA", "[DataCatalog] Execute Single Pipeline NUMA", benchQueriesNUMA)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkFrontPage", "[DataCatalog] Execute Pipeline FrontPage", benchQueriesFrontPage)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkMTMP", "[DataCatalog] Execute Multi Pipeline Remote", benchQueriesRemoteMT)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkLocalMTMP", "[DataCatalog] Execute Multi Pipeline MT Local", benchQueriesLocalMT)); - TaskManager::getInstance().registerTask(std::make_shared("benchmarkNUMAMTMP", "[DataCatalog] Execute Multi Pipeline MT NUMA", benchQueriesNUMAMT)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkRemote", "[DataCatalog] Execute Single Pipeline Remote", benchQueriesRemote)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkLocal", "[DataCatalog] Execute Single Pipeline Local", benchQueriesLocal)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkNUMA", "[DataCatalog] Execute Single Pipeline NUMA", benchQueriesNUMA)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkFrontPage", "[DataCatalog] Execute Pipeline FrontPage", benchQueriesFrontPage)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkMTMP", "[DataCatalog] Execute Multi Pipeline Remote", benchQueriesRemoteMT)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkLocalMTMP", "[DataCatalog] Execute Multi Pipeline MT Local", benchQueriesLocalMT)); + // TaskManager::getInstance().registerTask(std::make_shared("benchmarkNUMAMTMP", "[DataCatalog] Execute Multi Pipeline MT NUMA", benchQueriesNUMAMT)); + TaskManager::getInstance().registerTask(std::make_shared("benchmarksAll", "[DataCatalog] Execute All Benchmarks", benchmarksAllLambda)); TaskManager::getInstance().registerTask(std::make_shared("itTest", "[DataCatalog] IteratorTest", iteratorTestLambda)); - TaskManager::getInstance().registerTask(std::make_shared("pseudoPaxTest", "[DataCatalog] PseudoPaxTest", pseudoPaxLambda)); + // TaskManager::getInstance().registerTask(std::make_shared("pseudoPaxTest", "[DataCatalog] PseudoPaxTest", pseudoPaxLambda)); /* Message Layout * [ header_t | payload ] @@ -440,7 +438,6 @@ DataCatalog::DataCatalog() { */ CallbackFunction cb_sendInfo = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { reset_buffer(); - // std::cout << "[DataCatalog] Hello from the Data Catalog" << std::endl; const uint8_t code = static_cast(catalog_communication_code::receive_column_info); const size_t columnCount = cols.size(); @@ -449,8 +446,8 @@ DataCatalog::DataCatalog() { totalPayloadSize += sizeof(size_t); // store size of ident length in a 64bit int totalPayloadSize += col.first.size(); // actual c_string } - // std::cout << "[DataCatalog] Callback - allocating " << totalPayloadSize << " for column data." << std::endl; - char* data = (char*)malloc(totalPayloadSize); + LOG_DEBUG2("[DataCatalog] Callback - allocating " << totalPayloadSize << " for column data." << std::endl;) + char* data = reinterpret_cast(numa_alloc_onnode(totalPayloadSize, 0)); char* tmp = data; // How many columns does the receiver need to read @@ -472,10 +469,10 @@ DataCatalog::DataCatalog() { memcpy(tmp, col.first.c_str(), identlen); tmp += identlen; } - ConnectionManager::getInstance().sendData(conId, data, totalPayloadSize, nullptr, 0, code, Strategies::push); + ConnectionManager::getInstance().sendData(conId, data, totalPayloadSize, nullptr, 0, code); // Release temporary buffer - free(data); + numa_free(reinterpret_cast(data), totalPayloadSize); }; /* Message Layout @@ -484,8 +481,7 @@ DataCatalog::DataCatalog() { * [ columnInfoCount | [col_network_info, identLength, ident]* ] */ CallbackFunction cb_receiveInfo = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { - // package_t::header_t* head = reinterpret_cast(rcv_buffer->buf); - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getPayloadBasePtr(); size_t colCnt; memcpy(&colCnt, data, sizeof(size_t)); @@ -528,13 +524,13 @@ DataCatalog::DataCatalog() { */ auto fetchLambda = [this, conId]() -> void { print_all_remotes(); - std::cout << "[DataCatalog] Fetch data for which column?" << std::endl; + LOG_CONSOLE("[DataCatalog] Fetch data for which column?" << std::endl;) std::string ident; std::cin >> ident; std::cin.clear(); std::cin.ignore(10000, '\n'); - std::cout << "Fetch mode [1] whole column [2] (next) chunk" << std::endl; + LOG_CONSOLE("Fetch mode [1] whole column [2] (next) chunk" << std::endl;) size_t mode; std::cin >> mode; std::cin.clear(); @@ -551,7 +547,7 @@ DataCatalog::DataCatalog() { break; } default: { - std::cout << "[DataCatalog] No valid value selected, aborting." << std::endl; + LOG_WARNING("[DataCatalog] No valid value selected, aborting." << std::endl;) return; } } @@ -559,7 +555,6 @@ DataCatalog::DataCatalog() { if (!TaskManager::getInstance().hasTask("fetchColDataFromRemote")) { TaskManager::getInstance().registerTask(std::make_shared("fetchColDataFromRemote", "[DataCatalog] Fetch data from specific remote column", fetchLambda)); - std::cout << "[DataCatalog] Registered new Task!" << std::endl; } remoteInfoReady(); } @@ -575,9 +570,7 @@ DataCatalog::DataCatalog() { * [ columnNameLength, columnName ] */ CallbackFunction cb_fetchCol = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { - // package_t::header_t* head = reinterpret_cast(rcv_buffer->buf); - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); - // char* column_data = data + head->payload_start; + char* data = rcv_buffer->getPayloadBasePtr(); size_t identSz; memcpy(&identSz, data, sizeof(size_t)); @@ -607,7 +600,7 @@ DataCatalog::DataCatalog() { memcpy(tmp, &col->second->datatype, sizeof(col_data_t)); - ConnectionManager::getInstance().sendData(conId, (char*)col->second->data, col->second->sizeInBytes, appMetaData, appMetaSize, static_cast(catalog_communication_code::receive_column_data), Strategies::push); + ConnectionManager::getInstance().sendData(conId, (char*)col->second->data, col->second->sizeInBytes, appMetaData, appMetaSize, static_cast(catalog_communication_code::receive_column_data)); free(appMetaData); } @@ -618,11 +611,11 @@ DataCatalog::DataCatalog() { */ CallbackFunction cb_receiveCol = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // Package header - package_t::header_t* head = reinterpret_cast(rcv_buffer->getBufferPtr()); + package_t::header_t* head = reinterpret_cast(rcv_buffer->getFooterPtr()); // Start of AppMetaData - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getAppMetaPtr(); // Actual column data payload - char* column_data = data + head->payload_start; + char* column_data = rcv_buffer->getPayloadBasePtr(); size_t identSz; memcpy(&identSz, data, sizeof(size_t)); @@ -675,7 +668,7 @@ DataCatalog::DataCatalog() { if (col_network_info_iterator != remote_col_info.end()) { col = add_remote_column(ident, col_network_info_iterator->second); } else { - std::cout << "[DataCatalog] No Network info for received column " << ident << ", fetch column info first -- discarding message" << std::endl; + LOG_WARNING("[DataCatalog] No Network info for received column " << ident << ", fetch column info first -- discarding message" << std::endl;) return; } } @@ -702,7 +695,7 @@ DataCatalog::DataCatalog() { // Send a chunk of a column to the requester CallbackFunction cb_fetchColChunk = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // package_t::header_t* head = reinterpret_cast(rcv_buffer->buf); - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getPayloadBasePtr(); // char* column_data = data + head->payload_start; size_t identSz; @@ -770,7 +763,7 @@ DataCatalog::DataCatalog() { info->curr_offset += chunk_size; // std::cout << "Sent chunk. Offset now: " << info->curr_offset << " Total col size: " << info->col->sizeInBytes << std::endl; - ConnectionManager::getInstance().sendData(conId, data_start, chunk_size, appMetaData, appMetaSize, static_cast(catalog_communication_code::receive_column_chunk), Strategies::push); + ConnectionManager::getInstance().sendData(conId, data_start, chunk_size, appMetaData, appMetaSize, static_cast(catalog_communication_code::receive_column_chunk)); free(appMetaData); } @@ -783,11 +776,11 @@ DataCatalog::DataCatalog() { CallbackFunction cb_receiveColChunk = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // std::cout << "[DataCatalog] Received a message with a (part of a) column chnunk." << std::endl; // Package header - package_t::header_t* head = reinterpret_cast(rcv_buffer->getBufferPtr()); + package_t::header_t* head = reinterpret_cast(rcv_buffer->getFooterPtr()); // Start of AppMetaData - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getAppMetaPtr(); // Actual column data payload - char* column_data = data + head->payload_start; + char* column_data = rcv_buffer->getPayloadBasePtr(); size_t chunk_offset; memcpy(&chunk_offset, data, sizeof(size_t)); @@ -815,9 +808,9 @@ DataCatalog::DataCatalog() { if (col_network_info_iterator != remote_col_info.end()) { col = add_remote_column(ident, col_network_info_iterator->second); } else { - std::cout << "[DataCatalog] No Network info for received column " << ident << ", fetch column info first -- discarding message. Current CNI:" << std::endl; + LOG_WARNING("[DataCatalog] No Network info for received column " << ident << ", fetch column info first -- discarding message. Current CNI:" << std::endl;) for (auto k : remote_col_info) { - std::cout << k.first << " " << &k.second << std::endl; + LOG_WARNING(k.first << " " << &k.second << std::endl;) } return; } @@ -858,7 +851,7 @@ DataCatalog::DataCatalog() { */ CallbackFunction cb_fetchPseudoPax = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // package_t::header_t* head = reinterpret_cast(rcv_buffer->buf); - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getPayloadBasePtr(); size_t* ident_lens = reinterpret_cast(data); // Advance data to the first ident character @@ -1037,7 +1030,7 @@ DataCatalog::DataCatalog() { memcpy(tmp, &bpc, sizeof(size_t)); tmp += sizeof(size_t); - ConnectionManager::getInstance().sendData(conId, info->payload_buf + offset_size_pair.first, offset_size_pair.second, tmp_meta, info->metadata_size, static_cast(catalog_communication_code::receive_pseudo_pax), Strategies::push); + ConnectionManager::getInstance().sendData(conId, info->payload_buf + offset_size_pair.first, offset_size_pair.second, tmp_meta, info->metadata_size, static_cast(catalog_communication_code::receive_pseudo_pax)); free(tmp_meta); if (info->prepare_complete && info->prepared_offsets.empty()) { info->reset(); @@ -1053,11 +1046,11 @@ DataCatalog::DataCatalog() { */ CallbackFunction cb_receivePseudoPax = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // Package header - package_t::header_t* head = reinterpret_cast(rcv_buffer->getBufferPtr()); + package_t::header_t* head = reinterpret_cast(rcv_buffer->getFooterPtr()); // Start of AppMetaData - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getAppMetaPtr(); // Start of actual payload - char* pax_ptr = data + head->payload_start; + char* pax_ptr = rcv_buffer->getPayloadBasePtr(); size_t chunk_offset; memcpy(&chunk_offset, data, sizeof(size_t)); @@ -1121,7 +1114,7 @@ DataCatalog::DataCatalog() { CallbackFunction cb_reconfigureChunkSize = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { // package_t::header_t* head = reinterpret_cast(rcv_buffer->buf); - char* data = rcv_buffer->getBufferPtr() + sizeof(package_t::header_t); + char* data = rcv_buffer->getPayloadBasePtr(); uint64_t newChunkSize; memcpy(&newChunkSize, data, sizeof(uint64_t)); @@ -1148,6 +1141,33 @@ DataCatalog::DataCatalog() { reconfigure_done.notify_all(); }; + CallbackFunction cb_generateBenchmarkData = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { + uint64_t* data = reinterpret_cast(rcv_buffer->getPayloadBasePtr()); + bool createTables = *reinterpret_cast(reinterpret_cast(data) + (sizeof(uint64_t) * 6)); + + generateBenchmarkData(data[0], data[1], data[2], data[3], data[4], data[5], false, createTables); + reset_buffer(); + }; + + CallbackFunction cb_ackGenerateBenchmarkData = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { + reset_buffer(); + std::lock_guard lk(dataGenerationLock); + dataGenerationDone = true; + data_generation_done.notify_all(); + }; + + CallbackFunction cb_clearCatalog = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { + reset_buffer(); + DataCatalog::getInstance().clear(); + }; + + CallbackFunction cb_ackClearCatalog = [this](const size_t conId, const ReceiveBuffer* rcv_buffer, const std::_Bind reset_buffer) -> void { + reset_buffer(); + std::lock_guard lk(clearCatalogLock); + clearCatalogDone = true; + clear_catalog_done.notify_all(); + }; + registerCallback(static_cast(catalog_communication_code::send_column_info), cb_sendInfo); registerCallback(static_cast(catalog_communication_code::receive_column_info), cb_receiveInfo); registerCallback(static_cast(catalog_communication_code::fetch_column_data), cb_fetchCol); @@ -1158,6 +1178,10 @@ DataCatalog::DataCatalog() { registerCallback(static_cast(catalog_communication_code::receive_pseudo_pax), cb_receivePseudoPax); registerCallback(static_cast(catalog_communication_code::reconfigure_chunk_size), cb_reconfigureChunkSize); registerCallback(static_cast(catalog_communication_code::ack_reconfigure_chunk_size), cb_ackReconfigureChunkSize); + registerCallback(static_cast(catalog_communication_code::generate_benchmark_data), cb_generateBenchmarkData); + registerCallback(static_cast(catalog_communication_code::ack_generate_benchmark_data), cb_ackGenerateBenchmarkData); + registerCallback(static_cast(catalog_communication_code::clear_catalog), cb_clearCatalog); + registerCallback(static_cast(catalog_communication_code::ack_clear_catalog), cb_ackClearCatalog); } DataCatalog& @@ -1167,10 +1191,14 @@ DataCatalog::getInstance() { } DataCatalog::~DataCatalog() { - clear(); + clear(false, true); } -void DataCatalog::clear() { +void DataCatalog::clear(bool sendRemote, bool destructor) { + if (sendRemote) { + ConnectionManager::getInstance().sendOpCode(1, static_cast(catalog_communication_code::clear_catalog), true); + } + for (auto it : cols) { delete it.second; } @@ -1179,22 +1207,34 @@ void DataCatalog::clear() { delete it.second; } remote_cols.clear(); + + remote_col_info.clear(); + + tables.clear(); + + if (!destructor && sendRemote) { + std::unique_lock lk(clearCatalogLock); + if (!clearCatalogDone) { + clear_catalog_done.wait(lk, [this] { return clearCatalogDone; }); + } + } else if (!destructor) { + ConnectionManager::getInstance().sendOpCode(1, static_cast(catalog_communication_code::ack_clear_catalog), true); + } } void DataCatalog::registerCallback(uint8_t code, CallbackFunction cb) const { if (ConnectionManager::getInstance().registerCallback(code, cb)) { - std::cout << "[DataCatalog] Successfully added callback for code " << static_cast(code) << std::endl; + LOG_INFO("[DataCatalog] Successfully added callback for code " << static_cast(code) << std::endl;) } else { - std::cout << "[DataCatalog] Error adding callback for code " << static_cast(code) << std::endl; + LOG_WARNING("[DataCatalog] Error adding callback for code " << static_cast(code) << std::endl;) } } -col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, size_t elemCount) { - // std::cout << "Calling gen with type " << type << std::endl; +col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, size_t elemCount, int node) { auto it = cols.find(ident); if (it != cols.end()) { - std::cout << "Column width ident " << ident << " already present, returning old data." << std::endl; + LOG_INFO("Column width ident " << ident << " already present, returning old data." << std::endl;) return it; } @@ -1207,7 +1247,7 @@ col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, s case col_data_t::gen_smallint: { std::uniform_int_distribution distribution(0, 99); tmp->datatype = col_data_t::gen_smallint; - tmp->allocate_aligned_internal(elemCount); + tmp->allocate_on_numa(elemCount, node); auto data = reinterpret_cast(tmp->data); for (size_t i = 0; i < elemCount; ++i) { data[i] = distribution(generator); @@ -1216,9 +1256,9 @@ col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, s break; } case col_data_t::gen_bigint: { - std::uniform_int_distribution distribution(0, 99); + std::uniform_int_distribution distribution(0, 100); tmp->datatype = col_data_t::gen_bigint; - tmp->allocate_aligned_internal(elemCount); + tmp->allocate_on_numa(elemCount, node); auto data = reinterpret_cast(tmp->data); for (size_t i = 0; i < elemCount; ++i) { data[i] = distribution(generator); @@ -1229,7 +1269,7 @@ col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, s case col_data_t::gen_float: { std::uniform_real_distribution distribution(0, 50); tmp->datatype = col_data_t::gen_float; - tmp->allocate_aligned_internal(elemCount); + tmp->allocate_on_numa(elemCount, node); auto data = reinterpret_cast(tmp->data); for (size_t i = 0; i < elemCount; ++i) { data[i] = distribution(generator); @@ -1240,7 +1280,7 @@ col_dict_t::iterator DataCatalog::generate(std::string ident, col_data_t type, s case col_data_t::gen_double: { std::uniform_real_distribution distribution(0, 50); tmp->datatype = col_data_t::gen_double; - tmp->allocate_aligned_internal(elemCount); + tmp->allocate_on_numa(elemCount, node); auto data = reinterpret_cast(tmp->data); for (size_t i = 0; i < elemCount; ++i) { data[i] = distribution(generator); @@ -1272,60 +1312,82 @@ col_t* DataCatalog::find_remote(std::string ident) const { return nullptr; } +col_t* DataCatalog::add_column(std::string ident, col_t* col) { + return cols.insert({ident, col}).first->second; +} + col_t* DataCatalog::add_remote_column(std::string name, col_network_info ni) { std::lock_guard _lka(appendLock); auto it = remote_cols.find(name); if (it != remote_cols.end()) { - // std::cout << "[DataCatalog] Column with same ident ('" << name << "') already present, cannot add remote column." << std::endl; + LOG_INFO("[DataCatalog] Column with same ident ('" << name << "') already present, cannot add remote column." << std::endl;) return it->second; } else { - // std::cout << "[DataCatalog] Creating new remote column: " << name << std::endl; + LOG_DEBUG1("[DataCatalog] Creating new remote column: " << name << std::endl;) col_t* col = new col_t(); col->ident = name; col->is_remote = true; col->datatype = (col_data_t)ni.type_info; - col->allocate_aligned_internal((col_data_t)ni.type_info, ni.size_info); + col->allocate_on_numa((col_data_t)ni.type_info, ni.size_info, 0); remote_cols.insert({name, col}); return col; } } +std::vector DataCatalog::getLocalColumnNames() const { + std::vector out; + for (auto it : cols) { + out.push_back(it.first); + } + + return out; +} + +std::vector DataCatalog::getRemoteColumnNames() const { + std::vector out; + for (auto it : remote_cols) { + out.push_back(it.first); + } + + return out; +} + void DataCatalog::print_column(std::string& ident) const { auto it = cols.find(ident); if (it != cols.end()) { - std::cout << "[DataCatalog]" << (*it).second->print_data_head() << std::endl; + LOG_INFO("[DataCatalog]" << (*it).second->print_data_head() << std::endl;) } else { - std::cout << "[DataCatalog] No Entry for ident " << ident << std::endl; + LOG_WARNING("[DataCatalog] No Entry for ident " << ident << std::endl;) } } void DataCatalog::print_all() const { - std::cout << "### Local Data Catalog ###" << std::endl; + LOG_INFO("### Local Data Catalog ###" << std::endl;) if (cols.size() == 0) { - std::cout << "" << std::endl; + LOG_INFO("" << std::endl;) } for (auto it : cols) { - std::cout << "[" << it.first << "]: " << it.second->print_identity() << std::endl; + LOG_INFO("[" << it.first << "]: " << it.second->print_identity() << std::endl;) } } void DataCatalog::print_all_remotes() const { - std::cout << "### Remote Data Catalog ###" << std::endl; + LOG_INFO("### Remote Data Catalog ###" << std::endl;) if (remote_col_info.size() == 0) { - std::cout << "" << std::endl; + LOG_INFO("" << std::endl;) } for (auto it : remote_col_info) { - std::cout << "[" << it.first << "]: "; + LOG_INFO("[" << it.first << "]: ";) auto remote_col = remote_cols.find(it.first); if (remote_col != remote_cols.end()) { - std::cout << remote_col->second->print_identity(); + LOG_INFO(remote_col->second->print_identity();) auto rem_info = remote_col_info.find(it.first); - std::cout << " (" << rem_info->second.received_bytes << " received)"; + LOG_INFO(" (" << rem_info->second.received_bytes << " received)";) } else { - std::cout << it.second.print_identity() << " [nothing local]"; + LOG_INFO(it.second.print_identity() << " [nothing local]";) } - std::cout << std::endl; + LOG_INFO(std::endl;) } } @@ -1344,12 +1406,12 @@ void DataCatalog::eraseAllRemoteColumns() { } void DataCatalog::fetchColStub(std::size_t conId, std::string& ident, bool wholeColumn) const { - char* payload = (char*)malloc(ident.size() + sizeof(size_t)); + char* payload = reinterpret_cast(malloc(ident.size() + sizeof(size_t))); const size_t sz = ident.size(); memcpy(payload, &sz, sizeof(size_t)); memcpy(payload + sizeof(size_t), ident.c_str(), sz); catalog_communication_code code = wholeColumn ? catalog_communication_code::fetch_column_data : catalog_communication_code::fetch_column_chunk; - ConnectionManager::getInstance().sendData(conId, payload, sz + sizeof(size_t), nullptr, 0, static_cast(code), Strategies::push); + ConnectionManager::getInstance().sendData(conId, payload, sz + sizeof(size_t), nullptr, 0, static_cast(code)); free(payload); } @@ -1412,7 +1474,7 @@ void DataCatalog::fetchPseudoPax(std::size_t conId, std::vector ide tmp += id.size(); } const size_t total_payload_size = (sizeof(size_t) * (idents.size() + 1)) + string_sizes; - ConnectionManager::getInstance().sendData(conId, payload, total_payload_size, nullptr, 0, static_cast(catalog_communication_code::fetch_pseudo_pax), Strategies::push); + ConnectionManager::getInstance().sendData(conId, payload, total_payload_size, nullptr, 0, static_cast(catalog_communication_code::fetch_pseudo_pax)); free(payload); } @@ -1433,13 +1495,13 @@ void DataCatalog::fetchRemoteInfo() { // } // } remote_info_available.wait(lk, [this] { return col_info_received; }); -}; +} void DataCatalog::reconfigureChunkSize(const uint64_t newChunkSize, const uint64_t newChunkThreshold) { using namespace std::chrono_literals; if (newChunkSize == 0 || newChunkThreshold == 0) { - std::cout << "Either the new Chunk Size or the new Chunk Threshold was 0!" << std::endl; + LOG_WARNING("Either the new Chunk Size or the new Chunk Threshold was 0!" << std::endl;) return; } @@ -1450,6 +1512,73 @@ void DataCatalog::reconfigureChunkSize(const uint64_t newChunkSize, const uint64 std::unique_lock lk(reconfigure_lock); reconfigured = false; - ConnectionManager::getInstance().sendData(1, ptr, sizeof(uint64_t), nullptr, 0, static_cast(catalog_communication_code::reconfigure_chunk_size), Strategies::push); + ConnectionManager::getInstance().sendData(1, ptr, sizeof(uint64_t), nullptr, 0, static_cast(catalog_communication_code::reconfigure_chunk_size)); reconfigure_done.wait(lk, [this] { return reconfigured; }); +} + +void DataCatalog::generateBenchmarkData(const uint64_t distinctLocalColumns, const uint64_t remoteColumnsForLocal, const uint64_t localColumnElements, const uint64_t percentageOfRemote, const uint64_t localNumaNode, const uint64_t remoteNumaNode, bool sendToRemote, bool createTables) { + LOG_DEBUG1("Generating Benchmark Data" << std::endl;) + + const uint64_t remoteColumnSize = localColumnElements * percentageOfRemote * 0.01; + + if (sendToRemote) { + std::unique_lock lk(dataGenerationLock); + dataGenerationDone = false; + char* remInfos = reinterpret_cast(std::malloc(sizeof(uint64_t) * 6 + sizeof(bool))); + char* tmp = remInfos; + std::memcpy(reinterpret_cast(tmp), &distinctLocalColumns, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &remoteColumnsForLocal, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &localColumnElements, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &percentageOfRemote, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &localNumaNode, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &remoteNumaNode, sizeof(uint64_t)); + tmp += sizeof(uint64_t); + std::memcpy(reinterpret_cast(tmp), &createTables, sizeof(bool)); + + ConnectionManager::getInstance().sendData(1, remInfos, sizeof(uint64_t) * 6 + sizeof(bool), nullptr, 0, static_cast(catalog_communication_code::generate_benchmark_data)); + } + + if (createTables) { + LOG_DEBUG1("Creating Tables" << std::endl;) +#pragma omp parallel for schedule(static, 2) num_threads(8) + for (size_t i = 0; i < distinctLocalColumns; ++i) { + std::string name = "tab_" + std::to_string(i); + + DataCatalog::getInstance().tables.insert(std::make_pair(name, new table_t(name, remoteColumnsForLocal + 1, localColumnElements, 0, percentageOfRemote, true))); + + for (size_t j = 0; j < remoteColumnsForLocal; ++j) { + std::string sub_name = name + "_" + std::to_string(j); + DataCatalog::getInstance().tables.insert(std::make_pair(sub_name, new table_t(sub_name, 2, remoteColumnSize, 0, percentageOfRemote, false))); + } + } + } else { + LOG_DEBUG1("Creating Columns" << std::endl;) +#pragma omp parallel for schedule(static, 2) num_threads(8) + for (size_t i = 0; i < distinctLocalColumns; ++i) { + std::string name = "col_" + std::to_string(i); + + generate(name, col_data_t::gen_bigint, localColumnElements, localNumaNode); + + for (size_t j = 0; j < remoteColumnsForLocal; ++j) { + std::string sub_name = name + "_" + std::to_string(j); + generate(sub_name, col_data_t::gen_bigint, remoteColumnSize, remoteNumaNode); + } + } + } + + if (sendToRemote) { + std::unique_lock lk(dataGenerationLock); + if (!dataGenerationDone) { + data_generation_done.wait(lk, [this] { return dataGenerationDone; }); + } + } else { + ConnectionManager::getInstance().sendOpCode(1, static_cast(catalog_communication_code::ack_generate_benchmark_data), true); + } + + print_all(); } \ No newline at end of file diff --git a/src/Queries.cpp b/src/Queries.cpp index fcd4ccd..607c729 100644 --- a/src/Queries.cpp +++ b/src/Queries.cpp @@ -1,843 +1,751 @@ -#include -#include -#include - -#include - -size_t OPTIMAL_BLOCK_SIZE = 65536; - -std::chrono::duration waitingTime = std::chrono::duration::zero(); -std::chrono::duration workingTime = std::chrono::duration::zero(); - -void reset_timer() { - waitingTime = std::chrono::duration::zero(); - workingTime = std::chrono::duration::zero(); -} - -inline void wait_col_data_ready(col_t* _col, char* _data) { - auto s_ts = std::chrono::high_resolution_clock::now(); - std::unique_lock lk(_col->iteratorLock); - if (!(_data < static_cast(_col->current_end))) { - _col->iterator_data_available.wait(lk, [_col, _data] { return reinterpret_cast(_data) < static_cast(_col->current_end); }); - } - waitingTime += (std::chrono::high_resolution_clock::now() - s_ts); -}; - -template -inline std::vector less_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (reload) { - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (data[e] < predicate) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (data[e] < predicate) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector less_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (data[e] <= predicate) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (data[e] <= predicate) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector greater_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (data[e] > predicate) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (data[e] > predicate) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector greater_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (data[e] >= predicate) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (data[e] >= predicate) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (data[e] == predicate) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (data[e] == predicate) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector between_incl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (predicate_1 <= data[e] && data[e] <= predicate_2) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (predicate_1 <= data[e] && data[e] <= predicate_2) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -inline std::vector between_excl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { - auto data = reinterpret_cast(column->data) + offset; - if (remote) { - if (reload) { - if (!prefetching && !paxed) { - column->request_data(!chunked); - } - wait_col_data_ready(column, reinterpret_cast(data)); - if (prefetching && chunked && !paxed) { - column->request_data(!chunked); - } - } - } - - auto s_ts = std::chrono::high_resolution_clock::now(); - std::vector out_vec; - out_vec.reserve(blockSize); - if (isFirst) { - for (auto e = 0; e < blockSize; ++e) { - if (predicate_1 < data[e] && data[e] < predicate_2) { - out_vec.push_back(e); - } - } - } else { - for (auto e : in_pos) { - if (predicate_1 < data[e] && data[e] < predicate_2) { - out_vec.push_back(e); - } - } - } - - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - return out_vec; -}; - -template -uint64_t bench_1(const uint64_t predicate) { - col_t* lo_discount; - col_t* lo_quantity; - col_t* lo_extendedprice; - std::chrono::time_point s_ts; - const std::vector idents{"col_0", "col_1", "col_2"}; - - if (remote) { - lo_discount = DataCatalog::getInstance().find_remote("col_0"); - if (prefetching && !paxed) lo_discount->request_data(!chunked); - lo_quantity = DataCatalog::getInstance().find_remote("col_1"); - if (prefetching && !paxed) lo_quantity->request_data(!chunked); - lo_extendedprice = DataCatalog::getInstance().find_remote("col_2"); - if (prefetching && !paxed) lo_extendedprice->request_data(!chunked); - - if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } else { - lo_discount = DataCatalog::getInstance().find_local("col_0"); - lo_quantity = DataCatalog::getInstance().find_local("col_1"); - lo_extendedprice = DataCatalog::getInstance().find_local("col_2"); - } - - size_t columnSize = lo_discount->size; - - size_t max_elems_per_chunk = 0; - size_t currentBlockSize = max_elems_per_chunk; - if (paxed) { - size_t total_id_len = 0; - for (auto& id : idents) { - total_id_len += id.size(); - } - - const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; - const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); - - max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; - currentBlockSize = max_elems_per_chunk; - } else if (!(remote && (chunked || paxed))) { - max_elems_per_chunk = columnSize; - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } else { - max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); - if (max_elems_per_chunk <= OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { - currentBlockSize = max_elems_per_chunk; - } else { - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } - } - - uint64_t sum = 0; - size_t baseOffset = 0; - size_t currentChunkElementsProcessed = 0; - - auto data_le = reinterpret_cast(lo_extendedprice->data); - auto data_ld = reinterpret_cast(lo_discount->data); - - while (baseOffset < columnSize) { - if (remote && paxed) { - if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - wait_col_data_ready(lo_extendedprice, reinterpret_cast(data_le)); - if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } - - const size_t elem_diff = columnSize - baseOffset; - if (elem_diff < currentBlockSize) { - currentBlockSize = elem_diff; - } - - auto le_idx = greater_than(lo_extendedprice, 5, baseOffset, currentBlockSize, - less_than(lo_quantity, 25, baseOffset, currentBlockSize, - between_incl(lo_discount, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), - currentChunkElementsProcessed == 0); - - s_ts = std::chrono::high_resolution_clock::now(); - for (auto idx : le_idx) { - sum += (data_ld[idx] * data_le[idx]); - // ++sum; - } - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - baseOffset += currentBlockSize; - data_ld += currentBlockSize; - data_le += currentBlockSize; - currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; - } - - return sum; -} - -template -uint64_t bench_2(const uint64_t predicate) { - col_t* lo_discount; - col_t* lo_quantity; - col_t* lo_extendedprice; - std::chrono::time_point s_ts; - const std::vector idents{"col_0", "col_1", "col_2"}; - - if (remote) { - lo_quantity = DataCatalog::getInstance().find_remote("col_1"); - if (prefetching && !paxed) lo_quantity->request_data(!chunked); - lo_discount = DataCatalog::getInstance().find_remote("col_0"); - if (prefetching && !paxed) lo_discount->request_data(!chunked); - lo_extendedprice = DataCatalog::getInstance().find_remote("col_2"); - if (prefetching && !paxed) lo_extendedprice->request_data(!chunked); - - if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } else { - lo_discount = DataCatalog::getInstance().find_local("col_0"); - lo_quantity = DataCatalog::getInstance().find_local("col_1"); - lo_extendedprice = DataCatalog::getInstance().find_local("col_2"); - } - - size_t columnSize = lo_quantity->size; - - size_t max_elems_per_chunk = 0; - size_t currentBlockSize = max_elems_per_chunk; - if (paxed) { - size_t total_id_len = 0; - for (auto& id : idents) { - total_id_len += id.size(); - } - - const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; - const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); - - max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; - currentBlockSize = max_elems_per_chunk; - } else if (!(remote && (chunked || paxed))) { - max_elems_per_chunk = columnSize; - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } else { - max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); - if (max_elems_per_chunk <= OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { - currentBlockSize = max_elems_per_chunk; - } else { - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } - } - - uint64_t sum = 0; - size_t baseOffset = 0; - size_t currentChunkElementsProcessed = 0; - - auto data_le = reinterpret_cast(lo_extendedprice->data); - auto data_ld = reinterpret_cast(lo_discount->data); - - while (baseOffset < columnSize) { - if (remote && paxed) { - if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - wait_col_data_ready(lo_extendedprice, reinterpret_cast(data_le)); - if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } - - const size_t elem_diff = columnSize - baseOffset; - if (elem_diff < currentBlockSize) { - currentBlockSize = elem_diff; - } - - auto le_idx = less_than(lo_quantity, predicate, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0); - - if (remote && !paxed) { - if (currentChunkElementsProcessed == 0) { - if (!prefetching && chunked) { - lo_extendedprice->request_data(!chunked); - lo_discount->request_data(!chunked); - } - wait_col_data_ready(lo_extendedprice, reinterpret_cast(data_le)); - wait_col_data_ready(lo_discount, reinterpret_cast(data_ld)); - if (prefetching && chunked) { - lo_extendedprice->request_data(!chunked); - lo_discount->request_data(!chunked); - } - } - } - - s_ts = std::chrono::high_resolution_clock::now(); - for (auto idx : le_idx) { - sum += (data_ld[idx] * data_le[idx]); - // ++sum; - } - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - baseOffset += currentBlockSize; - data_ld += currentBlockSize; - data_le += currentBlockSize; - currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; - } - - return sum; -} - -template -uint64_t bench_3(const uint64_t predicate) { - col_t* column_0; - col_t* column_1; - col_t* column_2; - col_t* column_3; - std::chrono::time_point s_ts; - const std::vector idents{"col_0", "col_1", "col_2", "col_3"}; - - if (remote) { - column_0 = DataCatalog::getInstance().find_remote("col_0"); - if (prefetching && !paxed) column_0->request_data(!chunked); - column_1 = DataCatalog::getInstance().find_remote("col_1"); - if (prefetching && !paxed) column_1->request_data(!chunked); - column_2 = DataCatalog::getInstance().find_remote("col_2"); - if (prefetching && !paxed) column_2->request_data(!chunked); - column_3 = DataCatalog::getInstance().find_remote("col_3"); - if (prefetching && !paxed) column_3->request_data(!chunked); - - if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } else { - column_0 = DataCatalog::getInstance().find_local("col_0"); - column_1 = DataCatalog::getInstance().find_local("col_1"); - column_2 = DataCatalog::getInstance().find_local("col_2"); - column_3 = DataCatalog::getInstance().find_local("col_3"); - } - - size_t columnSize = column_0->size; - - size_t max_elems_per_chunk = 0; - size_t currentBlockSize = max_elems_per_chunk; - if (paxed) { - size_t total_id_len = 0; - for (auto& id : idents) { - total_id_len += id.size(); - } - - const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; - const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); - - max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; - currentBlockSize = max_elems_per_chunk; - } else if (!(remote && (chunked || paxed))) { - max_elems_per_chunk = columnSize; - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } else { - max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); - if (max_elems_per_chunk <= OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { - currentBlockSize = max_elems_per_chunk; - } else { - currentBlockSize = OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); - } - } - - uint64_t sum = 0; - size_t baseOffset = 0; - size_t currentChunkElementsProcessed = 0; - - auto data_2 = reinterpret_cast(column_2->data); - auto data_3 = reinterpret_cast(column_3->data); - - while (baseOffset < columnSize) { - if (remote && paxed) { - if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - wait_col_data_ready(column_3, reinterpret_cast(data_3)); - if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); - } - - const size_t elem_diff = columnSize - baseOffset; - if (elem_diff < currentBlockSize) { - currentBlockSize = elem_diff; - } - - auto le_idx = equal(column_3, 16, baseOffset, currentBlockSize, - greater_than(column_2, 5, baseOffset, currentBlockSize, - less_than(column_1, 25, baseOffset, currentBlockSize, - between_incl(column_0, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), - currentChunkElementsProcessed == 0), - currentChunkElementsProcessed == 0); - - s_ts = std::chrono::high_resolution_clock::now(); - for (auto idx : le_idx) { - sum += (data_2[idx] * data_3[idx]); - // ++sum; - } - workingTime += (std::chrono::high_resolution_clock::now() - s_ts); - - baseOffset += currentBlockSize; - data_2 += currentBlockSize; - data_3 += currentBlockSize; - currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; - } - - return sum; -} - -template -void doBenchmarkRemotes(Fn&& f1, Fn&& f2, Fn&& f3, Fn&& f4, Fn&& f5, std::ofstream& out, const uint64_t predicate) { - uint64_t sum = 0; - std::chrono::time_point s_ts; - std::chrono::time_point e_ts; - std::chrono::duration secs; - - for (size_t i = 0; i < 5; ++i) { - reset_timer(); - DataCatalog::getInstance().fetchRemoteInfo(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = f1(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << "Remote\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << "Remote\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - - for (uint64_t chunkSize = 1ull << 18; chunkSize <= 1ull << 27; chunkSize <<= 1) { - DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); - - reset_timer(); - DataCatalog::getInstance().fetchRemoteInfo(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = f2(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << "Remote\tChunked\tOper\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << "Remote\tChunked\tOper\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - - reset_timer(); - DataCatalog::getInstance().fetchRemoteInfo(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = f3(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << "Remote\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << "Remote\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - } - - reset_timer(); - DataCatalog::getInstance().fetchRemoteInfo(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = f4(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << "Remote\tPaxed\tOper\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << "Remote\tPaxed\tOper\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - - reset_timer(); - DataCatalog::getInstance().fetchRemoteInfo(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = f5(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << "Remote\tPaxed\tPipe\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << "Remote\tPaxed\tPipe\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - } -} +// #include +// #include +// #include + +// #include + +// #include "Benchmarks.hpp" +// #include "Operators.hpp" + +// std::chrono::duration waitingTime = std::chrono::duration::zero(); +// std::chrono::duration workingTime = std::chrono::duration::zero(); + +// inline void reset_timer() { +// waitingTime = std::chrono::duration::zero(); +// workingTime = std::chrono::duration::zero(); +// } + +// inline void wait_col_data_ready(col_t* _col, char* _data) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// std::unique_lock lk(_col->iteratorLock); +// if (!(_data < static_cast(_col->current_end))) { +// _col->iterator_data_available.wait(lk, [_col, _data] { return reinterpret_cast(_data) < static_cast(_col->current_end); }); +// } +// waitingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// }; + +// template +// inline void fetch_data(col_t* column, uint64_t* data, const bool reload) { +// if (remote) { +// if (reload) { +// if (!prefetching && !paxed) { +// column->request_data(!chunked); +// } +// } +// wait_col_data_ready(column, reinterpret_cast(data)); +// if (reload) { +// if (prefetching && chunked && !paxed) { +// column->request_data(!chunked); +// } +// } +// } +// } + +// template +// inline std::vector less_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::less_than(data, predicate, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::less_than(data, predicate, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector less_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::less_equal(data, predicate, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::less_equal(data, predicate, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector greater_than(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::greater_than(data, predicate, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::greater_than(data, predicate, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector greater_equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::greater_equal(data, predicate, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::greater_equal(data, predicate, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector equal(col_t* column, const uint64_t predicate, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::equal(data, predicate, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::equal(data, predicate, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector between_incl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::between_incl(data, predicate_1, predicate_2, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::between_incl(data, predicate_1, predicate_2, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// inline std::vector between_excl(col_t* column, const uint64_t predicate_1, const uint64_t predicate_2, const uint64_t offset, const size_t blockSize, const std::vector in_pos, const bool reload) { +// auto data = reinterpret_cast(column->data) + offset; + +// std::vector out_vec; + +// fetch_data(column, data, reload); + +// if (timings) { +// auto s_ts = std::chrono::high_resolution_clock::now(); +// out_vec = Operators::between_excl(data, predicate_1, predicate_2, blockSize, in_pos); +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); +// } else { +// out_vec = Operators::between_excl(data, predicate_1, predicate_2, blockSize, in_pos); +// } + +// return out_vec; +// }; + +// template +// uint64_t pipe_1(const uint64_t predicate, const std::vector idents) { +// col_t* col_0; +// col_t* col_1; +// col_t* col_2; + +// if (idents.size() != 3) { +// LOG_ERROR("The size of 'idents' was not equal to 3" << std::endl;) +// return 0; +// } + +// std::chrono::time_point s_ts; + +// if (remote) { +// col_0 = DataCatalog::getInstance().find_remote(idents[0]); +// if (prefetching && !paxed) col_0->request_data(!chunked); +// col_1 = DataCatalog::getInstance().find_remote(idents[1]); +// if (prefetching && !paxed) col_1->request_data(!chunked); +// col_2 = DataCatalog::getInstance().find_remote(idents[2]); +// if (prefetching && !paxed) col_2->request_data(!chunked); + +// // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// } else { +// col_0 = DataCatalog::getInstance().find_local(idents[0]); +// col_1 = DataCatalog::getInstance().find_local(idents[1]); +// col_2 = DataCatalog::getInstance().find_local(idents[2]); +// } + +// size_t columnSize = col_0->size; + +// size_t max_elems_per_chunk = 0; +// size_t currentBlockSize = max_elems_per_chunk; +// // if (paxed) { +// // size_t total_id_len = 0; +// // for (auto& id : idents) { +// // total_id_len += id.size(); +// // } + +// // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; +// // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + +// // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; +// // currentBlockSize = max_elems_per_chunk; +// // } else +// if (!(remote && (chunked || paxed))) { +// max_elems_per_chunk = columnSize; +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } else { +// max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); +// if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { +// currentBlockSize = max_elems_per_chunk; +// } else { +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } +// } + +// uint64_t sum = 0; +// size_t baseOffset = 0; +// size_t currentChunkElementsProcessed = 0; + +// auto data_col_2 = reinterpret_cast(col_2->data); +// auto data_col_0 = reinterpret_cast(col_0->data); + +// while (baseOffset < columnSize) { +// // if (remote && paxed) { +// // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); +// // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // } + +// const size_t elem_diff = columnSize - baseOffset; +// if (elem_diff < currentBlockSize) { +// currentBlockSize = elem_diff; +// } + +// auto le_idx = greater_than(col_2, 5, baseOffset, currentBlockSize, +// less_than(col_1, 25, baseOffset, currentBlockSize, +// between_incl(col_0, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), +// currentChunkElementsProcessed == 0); + +// s_ts = std::chrono::high_resolution_clock::now(); +// for (auto idx : le_idx) { +// sum += (data_col_0[idx] * data_col_2[idx]); +// // ++sum; +// } +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + +// baseOffset += currentBlockSize; +// data_col_0 += currentBlockSize; +// data_col_2 += currentBlockSize; +// currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; +// } + +// return sum; +// } + +// template +// uint64_t pipe_2(const uint64_t predicate, const std::vector idents) { +// col_t* col_0; +// col_t* col_1; +// col_t* col_2; + +// if (idents.size() != 3) { +// LOG_ERROR("The size of 'idents' was not equal to 3" << std::endl;) +// return 0; +// } + +// std::chrono::time_point s_ts; + +// if (remote) { +// col_1 = DataCatalog::getInstance().find_remote(idents[1]); +// if (prefetching && !paxed) col_1->request_data(!chunked); +// col_0 = DataCatalog::getInstance().find_remote(idents[0]); +// if (prefetching && !paxed) col_0->request_data(!chunked); +// col_2 = DataCatalog::getInstance().find_remote(idents[2]); +// if (prefetching && !paxed) col_2->request_data(!chunked); + +// // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// } else { +// col_0 = DataCatalog::getInstance().find_local(idents[0]); +// col_1 = DataCatalog::getInstance().find_local(idents[1]); +// col_2 = DataCatalog::getInstance().find_local(idents[2]); +// } + +// size_t columnSize = col_1->size; + +// size_t max_elems_per_chunk = 0; +// size_t currentBlockSize = max_elems_per_chunk; +// // if (paxed) { +// // size_t total_id_len = 0; +// // for (auto& id : idents) { +// // total_id_len += id.size(); +// // } + +// // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; +// // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + +// // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; +// // currentBlockSize = max_elems_per_chunk; +// // } else +// if (!(remote && (chunked || paxed))) { +// max_elems_per_chunk = columnSize; +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } else { +// max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); +// if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { +// currentBlockSize = max_elems_per_chunk; +// } else { +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } +// } + +// uint64_t sum = 0; +// size_t baseOffset = 0; +// size_t currentChunkElementsProcessed = 0; + +// auto data_col_2 = reinterpret_cast(col_2->data); +// auto data_col_0 = reinterpret_cast(col_0->data); + +// while (baseOffset < columnSize) { +// // if (remote && paxed) { +// // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); +// // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // } + +// const size_t elem_diff = columnSize - baseOffset; +// if (elem_diff < currentBlockSize) { +// currentBlockSize = elem_diff; +// } + +// auto le_idx = less_than(col_1, predicate, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0); + +// if (remote && !paxed) { +// if (currentChunkElementsProcessed == 0) { +// if (!prefetching && chunked) { +// col_2->request_data(!chunked); +// col_0->request_data(!chunked); +// } +// wait_col_data_ready(col_2, reinterpret_cast(data_col_2)); +// wait_col_data_ready(col_0, reinterpret_cast(data_col_0)); +// if (prefetching && chunked) { +// col_2->request_data(!chunked); +// col_0->request_data(!chunked); +// } +// } +// } + +// s_ts = std::chrono::high_resolution_clock::now(); +// for (auto idx : le_idx) { +// sum += (data_col_0[idx] * data_col_2[idx]); +// // ++sum; +// } +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + +// baseOffset += currentBlockSize; +// data_col_0 += currentBlockSize; +// data_col_2 += currentBlockSize; +// currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; +// } + +// return sum; +// } + +// template +// uint64_t pipe_3(const uint64_t predicate, const std::vector idents) { +// col_t* column_0; +// col_t* column_1; +// col_t* column_2; +// col_t* column_3; + +// if (idents.size() != 4) { +// LOG_ERROR("The size of 'idents' was not equal to 4" << std::endl;) +// return 0; +// } + +// std::chrono::time_point s_ts; + +// if (remote) { +// column_0 = DataCatalog::getInstance().find_remote(idents[0]); +// if (prefetching && !paxed) column_0->request_data(!chunked); +// column_1 = DataCatalog::getInstance().find_remote(idents[1]); +// if (prefetching && !paxed) column_1->request_data(!chunked); +// column_2 = DataCatalog::getInstance().find_remote(idents[2]); +// if (prefetching && !paxed) column_2->request_data(!chunked); +// column_3 = DataCatalog::getInstance().find_remote(idents[3]); +// if (prefetching && !paxed) column_3->request_data(!chunked); + +// // if (prefetching && paxed) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// } else { +// column_0 = DataCatalog::getInstance().find_local(idents[0]); +// column_1 = DataCatalog::getInstance().find_local(idents[1]); +// column_2 = DataCatalog::getInstance().find_local(idents[2]); +// column_3 = DataCatalog::getInstance().find_local(idents[3]); +// } + +// size_t columnSize = column_0->size; + +// size_t max_elems_per_chunk = 0; +// size_t currentBlockSize = max_elems_per_chunk; +// // if (paxed) { +// // size_t total_id_len = 0; +// // for (auto& id : idents) { +// // total_id_len += id.size(); +// // } + +// // const size_t appMetaSize = 3 * sizeof(size_t) + (sizeof(size_t) * idents.size()) + total_id_len; +// // const size_t maximumPayloadSize = ConnectionManager::getInstance().getConnectionById(1)->maxBytesInPayload(appMetaSize); + +// // max_elems_per_chunk = ((maximumPayloadSize / idents.size()) / (sizeof(uint64_t) * 4)) * 4; +// // currentBlockSize = max_elems_per_chunk; +// // } else +// if (!(remote && (chunked || paxed))) { +// max_elems_per_chunk = columnSize; +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } else { +// max_elems_per_chunk = DataCatalog::getInstance().dataCatalog_chunkMaxSize / sizeof(uint64_t); +// if (max_elems_per_chunk <= Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t)) { +// currentBlockSize = max_elems_per_chunk; +// } else { +// currentBlockSize = Benchmarks::OPTIMAL_BLOCK_SIZE / sizeof(uint64_t); +// } +// } + +// uint64_t sum = 0; +// size_t baseOffset = 0; +// size_t currentChunkElementsProcessed = 0; + +// auto data_2 = reinterpret_cast(column_2->data); +// auto data_3 = reinterpret_cast(column_3->data); + +// while (baseOffset < columnSize) { +// // if (remote && paxed) { +// // if (!prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // wait_col_data_ready(column_3, reinterpret_cast(data_3)); +// // if (prefetching) DataCatalog::getInstance().fetchPseudoPax(1, idents); +// // } + +// const size_t elem_diff = columnSize - baseOffset; +// if (elem_diff < currentBlockSize) { +// currentBlockSize = elem_diff; +// } + +// auto le_idx = equal(column_3, 16, baseOffset, currentBlockSize, +// greater_than(column_2, 5, baseOffset, currentBlockSize, +// less_than(column_1, 25, baseOffset, currentBlockSize, +// between_incl(column_0, 10, 30, baseOffset, currentBlockSize, {}, currentChunkElementsProcessed == 0), currentChunkElementsProcessed == 0), +// currentChunkElementsProcessed == 0), +// currentChunkElementsProcessed == 0); + +// s_ts = std::chrono::high_resolution_clock::now(); +// for (auto idx : le_idx) { +// sum += (data_2[idx] * data_3[idx]); +// // ++sum; +// } +// workingTime += (std::chrono::high_resolution_clock::now() - s_ts); + +// baseOffset += currentBlockSize; +// data_2 += currentBlockSize; +// data_3 += currentBlockSize; +// currentChunkElementsProcessed = baseOffset % max_elems_per_chunk; +// } + +// return sum; +// } + +// // template +// // void doBenchmarkRemotes(Fn&& f1, Fn&& f2, Fn&& f3, Fn&& f4, Fn&& f5, std::ofstream& out, const uint64_t predicate) { +// // uint64_t sum = 0; +// // std::chrono::time_point s_ts; +// // std::chrono::time_point e_ts; +// // std::chrono::duration secs; + +// // for (size_t i = 0; i < 5; ++i) { +// // reset_timer(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = f1(predicate); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << "Remote\tFull\tPipe\t" << Benchmarks::OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << "Remote\tFull\tPipe\t" << Benchmarks::OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); + +// // for (uint64_t chunkSize = 1ull << 18; chunkSize <= 1ull << 27; chunkSize <<= 1) { +// // DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); + +// // reset_timer(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = f2(predicate); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << "Remote\tChunked\tOper\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << "Remote\tChunked\tOper\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); + +// // reset_timer(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = f3(predicate); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << "Remote\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << "Remote\tChunked\tPipe\t" << +DataCatalog::getInstance().dataCatalog_chunkMaxSize << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // } + +// // reset_timer(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = f4(predicate); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << "Remote\tPaxed\tOper\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << "Remote\tPaxed\tOper\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); + +// // reset_timer(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = f5(predicate); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << "Remote\tPaxed\tPipe\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << "Remote\tPaxed\tPipe\t000000\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // } +// // } -template -uint64_t frontPage_1() { - uint64_t sum_1 = 0; - uint64_t sum_2 = 0; +// // template +// // uint64_t frontPage_1() { +// // uint64_t sum_1 = 0; +// // uint64_t sum_2 = 0; - DataCatalog::getInstance().fetchRemoteInfo(); - sum_1 = bench_1(0); - DataCatalog::getInstance().eraseAllRemoteColumns(); - DataCatalog::getInstance().fetchRemoteInfo(); - sum_2 = bench_3(0); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // sum_1 = pipe_1(0); +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // sum_2 = pipe_3(0); - return sum_1 + sum_2; -} +// // return sum_1 + sum_2; +// // } -template -uint64_t frontPage_2() { - uint64_t sum_1 = 0; - uint64_t sum_2 = 0; +// // template +// // uint64_t frontPage_2() { +// // uint64_t sum_1 = 0; +// // uint64_t sum_2 = 0; - DataCatalog::getInstance().fetchRemoteInfo(); - sum_1 = bench_1(0); - sum_2 = bench_3(0); +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // sum_1 = pipe_1(0); +// // sum_2 = pipe_3(0); - return sum_1 + sum_2; -} +// // return sum_1 + sum_2; +// // } -template -uint64_t frontPage_3() { - uint64_t sum_1 = 0; - uint64_t sum_2 = 0; +// // template +// // uint64_t frontPage_3() { +// // uint64_t sum_1 = 0; +// // uint64_t sum_2 = 0; - DataCatalog::getInstance().fetchRemoteInfo(); -#pragma omp parallel for schedule(static, 1) num_threads(2) - for (size_t i = 0; i < 2; ++i) { - if (i == 0) { - sum_1 = bench_1(0); - } else if (i == 1) { - sum_2 = bench_3(0); - } - } - - return sum_1 + sum_2; -} - -void doBenchmarkFrontPage(std::ofstream& out) { - uint64_t sum = 0; - std::chrono::time_point s_ts; - std::chrono::time_point e_ts; - std::chrono::duration secs; - uint64_t chunkSize = 1ull << 22; +// // DataCatalog::getInstance().fetchRemoteInfo(); +// // #pragma omp parallel for schedule(static, 1) num_threads(2) +// // for (size_t i = 0; i < 2; ++i) { +// // if (i == 0) { +// // sum_1 = pipe_1(0); +// // } else if (i == 1) { +// // sum_2 = pipe_3(0); +// // } +// // } + +// // return sum_1 + sum_2; +// // } + +// // void doBenchmarkFrontPage(std::ofstream& out) { +// // uint64_t sum = 0; +// // std::chrono::time_point s_ts; +// // std::chrono::time_point e_ts; +// // std::chrono::duration secs; +// // uint64_t chunkSize = 1ull << 22; - DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); +// // DataCatalog::getInstance().reconfigureChunkSize(chunkSize, chunkSize); - for (size_t i = 0; i < 5; ++i) { - reset_timer(); - s_ts = std::chrono::high_resolution_clock::now(); - sum = frontPage_1(); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << +chunkSize << "\t1\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << +chunkSize << "\t1\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - reset_timer(); - - s_ts = std::chrono::high_resolution_clock::now(); - sum = frontPage_2(); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << +chunkSize << "\t2\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << +chunkSize << "\t2\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - reset_timer(); - - s_ts = std::chrono::high_resolution_clock::now(); - sum = frontPage_2(); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << +chunkSize << "\t3\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << +chunkSize << "\t3\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - reset_timer(); - - s_ts = std::chrono::high_resolution_clock::now(); - sum = frontPage_3(); - e_ts = std::chrono::high_resolution_clock::now(); - - secs = e_ts - s_ts; - - out << +chunkSize << "\t4\t" << +sum << "\t" << waitingTime.count() / 2 << "\t" << secs.count() << std::endl - << std::flush; - std::cout << +chunkSize << "\t4\t" << +sum << "\t" << waitingTime.count() / 2 << "\t" << secs.count() << std::endl; - - DataCatalog::getInstance().eraseAllRemoteColumns(); - reset_timer(); - } -} - -void executeRemoteBenchmarkingQueries(std::string& logName) { - std::ofstream out; - out.open(logName, std::ios_base::app); - out << std::fixed << std::setprecision(7) << std::endl; - std::cout << std::fixed << std::setprecision(7) << std::endl; - const std::array predicates{1, 25, 50, 75, 100}; - - // - - doBenchmarkRemotes(bench_1, // Remote Full Pipe/Oper (difference due to block-wise evaluation not significant) - bench_1, // Remote Chunked Oper - bench_1, // Remote Chunked Pipe - bench_1, // Remote Paxed Oper - bench_1, // Remote Paxed Pipe - out, 0); - - for (const auto predicate : predicates) { - doBenchmarkRemotes(bench_2, // Remote Full Pipe/Oper (difference due to block-wise evaluation not significant) - bench_2, // Remote Chunked Oper - bench_2, // Remote Chunked Pipe - bench_2, // Remote Paxed Oper - bench_2, // Remote Paxed Pipe - out, predicate); - } - - out.close(); -} - -void executeFrontPageBenchmarkingQueries(std::string& logName) { - std::ofstream out; - out.open(logName, std::ios_base::app); - out << std::fixed << std::setprecision(7) << std::endl; - std::cout << std::fixed << std::setprecision(7) << std::endl; - - // - - doBenchmarkFrontPage(out); - - out.close(); -} - -void executeLocalBenchmarkingQueries(std::string& logName, std::string locality) { - std::ofstream out; - out.open(logName, std::ios_base::app); - out << std::fixed << std::setprecision(7) << std::endl; - std::cout << std::fixed << std::setprecision(7) << std::endl; - const std::array predicates{0, 1, 25, 50, 75, 100}; - uint64_t sum = 0; - std::chrono::_V2::system_clock::time_point s_ts; - std::chrono::_V2::system_clock::time_point e_ts; - - for (const auto predicate : predicates) { - for (size_t i = 0; i < 20; ++i) { - reset_timer(); - - if (predicate == 0) { - s_ts = std::chrono::high_resolution_clock::now(); - sum = bench_1(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - } else { - s_ts = std::chrono::high_resolution_clock::now(); - sum = bench_2(predicate); - e_ts = std::chrono::high_resolution_clock::now(); - } - - std::chrono::duration secs = e_ts - s_ts; - auto additional_time = secs.count() - (workingTime.count() + waitingTime.count()); - - out << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl - << std::flush; - std::cout << locality << "\tFull\tPipe\t" << OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << "\t" << additional_time << std::endl; - } - } - - out.close(); -} \ No newline at end of file +// // for (size_t i = 0; i < 5; ++i) { +// // reset_timer(); +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = frontPage_1(); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << +chunkSize << "\t1\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << +chunkSize << "\t1\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // reset_timer(); + +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = frontPage_2(); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << +chunkSize << "\t2\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << +chunkSize << "\t2\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // reset_timer(); + +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = frontPage_2(); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << +chunkSize << "\t3\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << +chunkSize << "\t3\t" << +sum << "\t" << waitingTime.count() << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // reset_timer(); + +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = frontPage_3(); +// // e_ts = std::chrono::high_resolution_clock::now(); + +// // secs = e_ts - s_ts; + +// // out << +chunkSize << "\t4\t" << +sum << "\t" << waitingTime.count() / 2 << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << +chunkSize << "\t4\t" << +sum << "\t" << waitingTime.count() / 2 << "\t" << secs.count() << std::endl; + +// // DataCatalog::getInstance().eraseAllRemoteColumns(); +// // reset_timer(); +// // } +// // } + +// // void executeRemoteBenchmarkingQueries(std::string& logName) { +// // std::ofstream out; +// // out.open(logName, std::ios_base::app); +// // out << std::fixed << std::setprecision(7) << std::endl; +// // std::cout << std::fixed << std::setprecision(7) << std::endl; +// // const std::array predicates{1, 25, 50, 75, 100}; + +// // // + +// // doBenchmarkRemotes(pipe_1, // Remote Full Pipe/Oper (difference due to block-wise evaluation not significant) +// // pipe_1, // Remote Chunked Oper +// // pipe_1, // Remote Chunked Pipe +// // pipe_1, // Remote Paxed Oper +// // pipe_1, // Remote Paxed Pipe +// // out, 0); + +// // for (const auto predicate : predicates) { +// // doBenchmarkRemotes(pipe_2, // Remote Full Pipe/Oper (difference due to block-wise evaluation not significant) +// // pipe_2, // Remote Chunked Oper +// // pipe_2, // Remote Chunked Pipe +// // pipe_2, // Remote Paxed Oper +// // pipe_2, // Remote Paxed Pipe +// // out, predicate); +// // } + +// // out.close(); +// // } + +// // void executeFrontPageBenchmarkingQueries(std::string& logName) { +// // std::ofstream out; +// // out.open(logName, std::ios_base::app); +// // out << std::fixed << std::setprecision(7) << std::endl; +// // std::cout << std::fixed << std::setprecision(7) << std::endl; + +// // // + +// // doBenchmarkFrontPage(out); + +// // out.close(); +// // } + +// // void executeLocalBenchmarkingQueries(std::string& logName, std::string locality) { +// // std::ofstream out; +// // out.open(logName, std::ios_base::app); +// // out << std::fixed << std::setprecision(7) << std::endl; +// // std::cout << std::fixed << std::setprecision(7) << std::endl; +// // const std::array predicates{0, 1, 25, 50, 75, 100}; +// // uint64_t sum = 0; +// // std::chrono::_V2::system_clock::time_point s_ts; +// // std::chrono::_V2::system_clock::time_point e_ts; + +// // for (const auto predicate : predicates) { +// // for (size_t i = 0; i < 20; ++i) { +// // reset_timer(); + +// // if (predicate == 0) { +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = pipe_1(predicate, {"col_0", "col_1", "col_2"}); +// // e_ts = std::chrono::high_resolution_clock::now(); +// // } else { +// // s_ts = std::chrono::high_resolution_clock::now(); +// // sum = pipe_2(predicate, {"col_0", "col_1", "col_2"}); +// // e_ts = std::chrono::high_resolution_clock::now(); +// // } + +// // std::chrono::duration secs = e_ts - s_ts; +// // auto additional_time = secs.count() - (workingTime.count() + waitingTime.count()); + +// // out << locality << "\tFull\tPipe\t" << Benchmarks::OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << std::endl +// // << std::flush; +// // std::cout << locality << "\tFull\tPipe\t" << Benchmarks::OPTIMAL_BLOCK_SIZE << "\t" << +predicate << "\t" << sum << "\t" << waitingTime.count() << "\t" << workingTime.count() << "\t" << secs.count() << "\t" << additional_time << std::endl; +// // } +// // } + +// // out.close(); +// // } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 332ad49..31907fd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,34 +3,74 @@ #include #include #include +#include +#include #include #include #include +#include "Benchmarks.hpp" #include "Column.h" #include "DataCatalog.h" +#include "Logger.h" +#include "Worker.hpp" -int main() { - std::cout << "Generating Dummy Test Data" << std::endl; +void signal_handler(int signal) { + switch (signal) { + case SIGINT: { + ConnectionManager::getInstance().stop(true); + std::_Exit(EXIT_FAILURE); + } break; + case SIGUSR1: { + ConnectionManager::getInstance().stop(false); + std::_Exit(EXIT_SUCCESS); + } break; + default: { + std::cerr << "Unexpected signal " << signal << " received!\n"; + } break; + } + std::_Exit(EXIT_FAILURE); +} + +bool checkLinkUp() { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen("ibstat", "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return (result.find("State: Active") != std::string::npos); +} + +using namespace memordma; - size_t lineorderSize = 200000000; +int main(int argc, char *argv[]) { + for (auto sig : {SIGINT, SIGUSR1}) { + auto previous_handler = std::signal(sig, signal_handler); + if (previous_handler == SIG_ERR) { + std::cerr << "Setup of custom signal handler failed!\n"; + return EXIT_FAILURE; + } + } + ConnectionManager::getInstance().configuration->add(argc, argv); + Logger::LoadConfiguration(); -#pragma omp parallel for schedule(static, 2) num_threads(6) - for (size_t i = 0; i < 12; ++i) { - std::stringstream logNameStream; - logNameStream << "col_" << i; - DataCatalog::getInstance().generate(logNameStream.str(), col_data_t::gen_bigint, lineorderSize); + if (!checkLinkUp()) { + LOG_FATAL("Could not find 'Active' state in ibstat, please check! Maybe you need to run \"sudo opensm -B\" on any server." << std::endl); + exit(-2); } - DataCatalog::getInstance().print_all(); + struct bitmask *mask = numa_bitmask_alloc(numa_num_possible_nodes()); + numa_bitmask_setbit(mask, 0); + numa_bind(mask); + numa_bitmask_free(mask); - config_t config = {.dev_name = "", - .server_name = "", - .tcp_port = 20000, - .client_mode = false, - .ib_port = 1, - .gid_idx = -1}; + DataCatalog::getInstance(); + Benchmarks::getInstance(); bool abort = false; auto globalExit = [&]() -> void { @@ -38,12 +78,16 @@ int main() { using namespace std::chrono_literals; std::this_thread::sleep_for(500ms); } - ConnectionManager::getInstance().stop(true); abort = true; + ConnectionManager::getInstance().stop(true); }; TaskManager::getInstance().setGlobalAbortFunction(globalExit); - ConnectionManager::getInstance(); + if (ConnectionManager::getInstance().configuration->get(MEMO_DEFAULT_CONNECTION_AUTO_LISTEN)) { + std::thread([]() -> void { TaskManager::getInstance().executeByIdent("listenConnection"); }).detach(); + } else if (ConnectionManager::getInstance().configuration->get(MEMO_DEFAULT_CONNECTION_AUTO_INITIATE)) { + std::thread([]() -> void { TaskManager::getInstance().executeByIdent("openConnection"); }).detach(); + } std::string content; std::string op; @@ -51,15 +95,15 @@ int main() { while (!abort) { op = "-1"; TaskManager::getInstance().printAll(); - std::cout << "Type \"exit\" to terminate." << std::endl; - // std::cin >> op; + LOG_NOFORMAT("Type \"exit\" to terminate." << std::endl); + std::getline(std::cin, op, '\n'); if (op == "-1") { globalExit(); continue; } - std::cout << "Chosen:" << op << std::endl; + LOG_DEBUG1("Chosen:" << op << std::endl); std::transform(op.begin(), op.end(), op.begin(), [](unsigned char c) { return std::tolower(c); }); if (op == "exit") { @@ -71,7 +115,7 @@ int main() { id = stol(op); converted = true; } catch (...) { - std::cout << "[Error] No number given." << std::endl; + LOG_ERROR("No number given." << std::endl); continue; } if (converted) { @@ -79,4 +123,6 @@ int main() { } } } + + return 0; } \ No newline at end of file