Cod sursa(job #2473816)

Utilizator Kln1000Ciobanu Bogdan Kln1000 Data 14 octombrie 2019 12:41:38
Problema A+B Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.39 kb
// Copyright 2019 Ciobanu Bogdan-Calin
// [email protected]

#include <fstream>
#include <cstdint>
#include <vector>
#include <immintrin.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

using namespace std;

#pragma GCC diagnostic ignored "-Wpsabi"
#pragma GCC target ("arch=skylake-avx512")

class mapping_writer {
public:
    mapping_writer() {
        // DEFAULT C-TOR
    };

    mapping_writer(const char* file_name) {
        fd = open(file_name, O_RDWR | O_CREAT, (mode_t)0600);
        index &= 0;
        buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
        buffer_sizes.push_back(0);
        active_buffer &= 0;
    }

    template <typename T>
    inline mapping_writer& operator <<(T target) {
        auto inc = [&, this]() mutable {
            if (++index == SIZE) {
                index &= 0;
                buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
                buffer_sizes.push_back(index);
                ++active_buffer;
            }
        };

        aux &= 0;
        if (target == 0) {
            buffers[active_buffer][index] = '0';
            inc();
            return *this;
        }
        for (; target; target = target / 10)
            nr[aux++] = target % 10 + '0';
        for (; aux; inc())
            buffers[active_buffer][index] = nr[--aux];
        buffer_sizes[active_buffer] = index;
        return *this;
    }

    inline mapping_writer& operator <<(const char* target) {
        auto inc = [&, this]() mutable {
            if (++index == SIZE) {
                index &= 0;
                buffers.push_back((char*)mmap(0, SIZE, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
                buffer_sizes.push_back(index);
                ++active_buffer;
            }
        };

        aux &= 0;
        while (target[aux])
            buffers[active_buffer][index] = target[aux++], inc();
        return *this;
    }

    ~mapping_writer() {
        size_t total_size = 0;
        for (auto i : buffer_sizes)
            total_size += i;

        lseek(fd, total_size - 1, SEEK_SET);
        write(fd, "", 1);

        char* map = (char*)mmap(0, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

        for (unsigned i = 0, accumulated = 0; i < buffers.size(); ++i) {
            fastMemcpy(map + accumulated, buffers[i], buffer_sizes[i]);
            munmap(buffers[i], buffer_sizes[i]);
            accumulated += buffer_sizes[i];
        }


        msync(map, total_size, MS_SYNC);
        munmap(map, total_size);
        close(fd);
    }

private:
    static const int SIZE = 0x200000; ///2MB
    std::vector<char*> buffers;
    std::vector<size_t> buffer_sizes;
    int fd, index, aux, active_buffer;
    char nr[24];

    inline static void fastMemcpy(void* pvDest, void* pvSrc, size_t nBytes) {
        const __m256i* pSrc = reinterpret_cast<const __m256i*>(pvSrc);
        __m256i* pDest = reinterpret_cast<__m256i*>(pvDest);
        int64_t nVects = nBytes / sizeof(*pSrc);
        for (; nVects; --nVects, ++pSrc, ++pDest) {
            const __m256i loaded = _mm256_stream_load_si256(pSrc);
            _mm256_stream_si256(pDest, loaded);
        }
        _mm_sfence();
    }
};



int main() {
    ifstream f("adunare.in");
    mapping_writer t("adunare.out");
    int a, b;
    f >> a >> b;
    t << a + b << "\n";
    return 0;
}