Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include "shared_structures.h"
- #include <iostream>
- #include <fstream>
- #include <cassert>
- #include <queue>
- // Аллокатор "shared"-памяти (тут используем свой)
- std::vector<void*> to_be_free;
- void* shared_allocator(std::size_t size) {
- assert(size != 0);
- void* res = malloc(size);
- to_be_free.push_back(res);
- std::cout << "Allocated " << size << " bytes at " << res << "\n";
- return res;
- }
- // Наследуемся от can_be shared,
- // чтобы показать, что наша структура может быть
- // размещена в shared-памяти
- struct shared_stack : can_be_shared {
- // Указатели на наши данные
- int* size; // размер стека
- int* top_; // вершина стека
- int* data; // массив данных
- // Конструктор: max_size - максимальный размер стека
- // этот конструктор используется чтобы создавать новые
- // стеки, чтобы использовать существующий надо написать
- // второй конструктор - он ниже
- shared_stack(int max_size) :
- can_be_shared({
- // Поля структуры
- field(&size, max_size),
- field(&top_, 0),
- // массив размера max_size, init_data
- // инициализирует значения массива
- array(&data, max_size, init_data)
- }) {}
- // Инициализует массив data:
- // what - что проинициализовать, idx - индекс элемента
- static void init_data(int& what, std::size_t idx) {
- what = 0;
- }
- // Конструктор по стеку, который уже лежит по адресу ptr
- shared_stack(void* ptr) :
- // Указываем, что создаём объект из уже созданного
- from_existing(ptr),
- // и передаём поля для подстановки указателей
- can_be_shared({
- existing_field(&size),
- existing_field(&top_),
- existing_array(&data)
- }) {}
- // Стандартная реализация стека
- int& top() {
- return data[*top_ - 1];
- }
- void pop() {
- (*top_)--;
- }
- void push(int x) {
- data[(*top_)++] = x;
- }
- bool empty() {
- return !(*top_);
- }
- };
- struct many_stacks : can_be_shared {
- shared_stack* stacks;
- static void init_fn(shared_stack& what,
- std::size_t idx,
- const std::vector<size_t>& orig_sizes) {
- // Так как память, лежащая по адресу &what еще
- // не инициализирована, необходимо вызывать конструктор
- // вот таким вот незатейливым образом
- new(&what) shared_stack(orig_sizes[idx]);
- }
- many_stacks(const std::vector<std::size_t>& sizes) :
- can_be_shared({
- array(&stacks, sizes.size(), init_fn, sizes)
- }) {};
- many_stacks(void* ptr) :
- from_existing(ptr),
- can_be_shared({
- existing_array(&stacks)
- }) {};
- };
- #include <chrono>
- int main() {
- int N = 1000000;
- std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
- shared_stack stack(N);
- std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
- std::cout << "Create = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
- begin = std::chrono::steady_clock::now();
- void* save_ptr = stack.make_shared(shared_allocator);
- end = std::chrono::steady_clock::now();
- std::cout << "Make shared = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
- begin = std::chrono::steady_clock::now();
- shared_stack ref(save_ptr);
- end = std::chrono::steady_clock::now();
- std::cout << "Attach = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
- begin = std::chrono::steady_clock::now();
- for (int i = 0; i < N / 2; ++i) {
- stack.push(i);
- ref.push(i * 2);
- }
- while (!stack.empty()) {
- if (stack.top() != ref.top()) {
- exit(-1);
- }
- stack.pop();
- }
- end = std::chrono::steady_clock::now();
- std::cout << "Push&pop = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
- std::vector<int> v;
- std::vector<int>& v_ = v;
- v.reserve(N);
- begin = std::chrono::steady_clock::now();
- for (int i = 0; i < N / 2; ++i) {
- v.push_back(i);
- v_.push_back(i * 2);
- }
- while (!v.empty()) {
- if (v.back() != v_.back()) {
- exit(-1);
- }
- v.pop_back();
- }
- end = std::chrono::steady_clock::now();
- std::cout << "Push&pop(vector) = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
- for (auto& e : to_be_free) {
- free(e);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement