Advertisement
Guest User

Untitled

a guest
Mar 30th, 2022
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.80 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include "shared_structures.h"
  3. #include <iostream>
  4. #include <fstream>
  5. #include <cassert>
  6. #include <queue>
  7. // Аллокатор "shared"-памяти (тут используем свой)
  8. std::vector<void*> to_be_free;
  9. void* shared_allocator(std::size_t size) {
  10.     assert(size != 0);
  11.     void* res = malloc(size);
  12.     to_be_free.push_back(res);
  13.     std::cout << "Allocated " << size << " bytes at " << res << "\n";
  14.     return res;
  15. }
  16.  
  17. // Наследуемся от can_be shared,
  18. // чтобы показать, что наша структура может быть
  19. // размещена в shared-памяти
  20. struct shared_stack : can_be_shared {
  21.     // Указатели на наши данные
  22.     int* size; // размер стека
  23.     int* top_; // вершина стека
  24.     int* data; // массив данных
  25.  
  26.     // Конструктор: max_size - максимальный размер стека
  27.     // этот конструктор используется чтобы создавать новые
  28.     // стеки, чтобы использовать существующий надо написать
  29.     // второй конструктор - он ниже
  30.     shared_stack(int max_size) :
  31.         can_be_shared({
  32.         // Поля структуры
  33.         field(&size, max_size),
  34.         field(&top_, 0),
  35.         // массив размера max_size, init_data
  36.         // инициализирует значения массива
  37.         array(&data, max_size, init_data)
  38.             }) {}
  39.  
  40.     // Инициализует массив data:
  41.     // what - что проинициализовать, idx - индекс элемента
  42.     static void init_data(int& what, std::size_t idx) {
  43.         what = 0;
  44.     }
  45.  
  46.     // Конструктор по стеку, который уже лежит по адресу ptr
  47.     shared_stack(void* ptr) :
  48.         // Указываем, что создаём объект из уже созданного
  49.         from_existing(ptr),
  50.         // и передаём поля для подстановки указателей
  51.         can_be_shared({
  52.             existing_field(&size),
  53.             existing_field(&top_),
  54.             existing_array(&data)
  55.             }) {}
  56.     // Стандартная реализация стека
  57.     int& top() {
  58.         return data[*top_ - 1];
  59.     }
  60.  
  61.     void pop() {
  62.         (*top_)--;
  63.     }
  64.  
  65.     void push(int x) {
  66.         data[(*top_)++] = x;
  67.     }
  68.  
  69.     bool empty() {
  70.         return !(*top_);
  71.     }
  72. };
  73.  
  74. struct many_stacks : can_be_shared {
  75.     shared_stack* stacks;
  76.  
  77.     static void init_fn(shared_stack& what,
  78.         std::size_t idx,
  79.         const std::vector<size_t>& orig_sizes) {
  80.         // Так как память, лежащая по адресу &what еще
  81.         // не инициализирована, необходимо вызывать конструктор
  82.         // вот таким вот незатейливым образом
  83.         new(&what) shared_stack(orig_sizes[idx]);
  84.     }
  85.  
  86.     many_stacks(const std::vector<std::size_t>& sizes) :
  87.         can_be_shared({
  88.             array(&stacks, sizes.size(), init_fn, sizes)
  89.             }) {};
  90.  
  91.     many_stacks(void* ptr) :
  92.         from_existing(ptr),
  93.         can_be_shared({
  94.             existing_array(&stacks)
  95.             }) {};
  96. };
  97.  
  98. #include <chrono>
  99.  
  100. int main() {
  101.     int N = 1000000;
  102.     std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
  103.     shared_stack stack(N);
  104.     std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
  105.     std::cout << "Create = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  106.     begin = std::chrono::steady_clock::now();
  107.     void* save_ptr = stack.make_shared(shared_allocator);
  108.     end = std::chrono::steady_clock::now();
  109.     std::cout << "Make shared = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  110.     begin = std::chrono::steady_clock::now();
  111.     shared_stack ref(save_ptr);
  112.     end = std::chrono::steady_clock::now();
  113.     std::cout << "Attach = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  114.     begin = std::chrono::steady_clock::now();
  115.     for (int i = 0; i < N / 2; ++i) {
  116.         stack.push(i);
  117.         ref.push(i * 2);
  118.     }
  119.     while (!stack.empty()) {
  120.         if (stack.top() != ref.top()) {
  121.             exit(-1);
  122.         }
  123.         stack.pop();
  124.     }
  125.     end = std::chrono::steady_clock::now();
  126.     std::cout << "Push&pop = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  127.  
  128.     std::vector<int> v;
  129.     std::vector<int>& v_ = v;
  130.     v.reserve(N);
  131.     begin = std::chrono::steady_clock::now();
  132.     for (int i = 0; i < N / 2; ++i) {
  133.         v.push_back(i);
  134.         v_.push_back(i * 2);
  135.     }
  136.     while (!v.empty()) {
  137.         if (v.back() != v_.back()) {
  138.             exit(-1);
  139.         }
  140.         v.pop_back();
  141.     }
  142.     end = std::chrono::steady_clock::now();
  143.     std::cout << "Push&pop(vector) = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl;
  144.  
  145.  
  146.     for (auto& e : to_be_free) {
  147.         free(e);
  148.     }
  149.     return 0;
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement