Pagini recente » Cod sursa (job #168759) | Cod sursa (job #2851037) | Cod sursa (job #203380) | Cod sursa (job #1573180) | Cod sursa (job #2473816)
// 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;
}