LINUX.ORG.RU

Нужна помочь владельцев core2 в измерении производительности программы

 , , ,


0

3

Есть программа.

#include <boost/hana.hpp>
#include <limits>
#include <array>
#include <sys/mman.h>
#include <unistd.h>
#include <cassert>
#include <filesystem>
#include <string_view>
#include <vector>

namespace hana = boost::hana;
namespace fs = std::filesystem;

using namespace hana::literals;

using sv = std::string_view;

using hana::_;


constexpr uint8_t swmap(uint8_t c) {
  switch(c) {
    case 'A': case 'a': return 'T';// 'A' | 'a' => 'T',
    case 'C': case 'c': return 'G';// 'C' | 'c' => 'G',
    case 'G': case 'g': return 'C';// 'G' | 'g' => 'C',
    case 'T': case 't': return 'A';// 'T' | 't' => 'A',
    case 'U': case 'u': return 'A';// 'U' | 'u' => 'A',
    case 'M': case 'm': return 'K';// 'M' | 'm' => 'K',
    case 'R': case 'r': return 'Y';// 'R' | 'r' => 'Y',
    case 'W': case 'w': return 'W';// 'W' | 'w' => 'W',
    case 'S': case 's': return 'S';// 'S' | 's' => 'S',
    case 'Y': case 'y': return 'R';// 'Y' | 'y' => 'R',
    case 'K': case 'k': return 'M';// 'K' | 'k' => 'M',
    case 'V': case 'v': return 'B';// 'V' | 'v' => 'B',
    case 'H': case 'h': return 'D';// 'H' | 'h' => 'D',
    case 'D': case 'd': return 'H';// 'D' | 'd' => 'H',
    case 'B': case 'b': return 'V';// 'B' | 'b' => 'V',
    case 'N': case 'n': return 'N';// 'N' | 'n' => 'N',
    default: return 0;
  }
}

constexpr auto map = ([] {
  constexpr auto max = std::numeric_limits<uint8_t>::max();
  std::array<uint16_t, max * max> map{};
  for(size_t it = 0; it < map.size(); ++it) {
    uint8_t hi = (it >> 8), lo = it;
    map[it] = (swmap(lo) << 8) | (swmap(hi));
  }
  return map;
})();

constexpr auto map256 = ([] {
  constexpr auto max = std::numeric_limits<uint8_t>::max();
  std::array<uint8_t, max> map{};
  for(size_t it = 0; it < max; ++it)
    map[it] = swmap(it);
  return map;
})();

template<size_t noffset> void replace60(const char * in, char * out) {
  constexpr auto offset = hana::llong_c<noffset>;
  
  auto op = [&] {
    *(uint16_t *)out = map[*(const uint16_t *)(in -= 2)];
    out += 2;
  };
  
  auto tail_size = ((60_c - offset) / 2_c);
  tail_size.times(op);
  
  if constexpr(offset % 2_c) {
//   ...1\n  
//   0...  
    *out++ = map256[*(--in)];
    --in;
//     assert(*in == '\n');
    *out++ = map256[*(--in)];
    (29_c - tail_size).times(op);
  } else {// even
//   ...\n  
//   ...  
    in -= 1;
//     assert(*in == '\n');
    (30_c - tail_size).times(op);
  }
  *(out++) = '\n';
}

auto select_replace60 = [](std::string_view in) {
  constexpr static auto replace60_map = ([] {
    std::array<decltype(replace60<0>) *, 60> map{};
    (60_c).times.with_index([&](auto index) {
      map[index()] = replace60<index()>;
    });
    return map;
  })();
  
  auto first_pos = size(in) - 1;
  assert(in.at(first_pos) == '\n');
  
  auto diff = first_pos - in.find_last_of('\n', first_pos - 1);
  assert(in.at(size(in) - diff - 1) == '\n');
  
  return replace60_map.at(61 - diff);
};


void replace(sv data) {
  auto op = select_replace60(data);
  constexpr size_t line_size = 61;
  constexpr size_t buff_size = line_size * 1024;
  char buff[buff_size] = {};
  auto n = size(data) / line_size;
  auto tail = size(data) - (n * line_size);
  
  auto it = end(data) - 1;
  auto buff_it = std::begin(buff);
  
  while(n--) {
    op(it, buff_it);
    buff_it += line_size;
    it -= line_size;
    if(buff_it == (std::end(buff) - line_size)) {
      write(STDOUT_FILENO, buff, buff_size - line_size);
      buff_it = buff;
    }
  }
  if(tail) {
    while(tail--) {
      if(*(--it) == '\n') continue;
      *buff_it++ = map256[*it];
    }
    *buff_it++ = '\n';
  }
  write(STDOUT_FILENO, buff, buff_it - std::begin(buff));
}

template<typename F> __attribute_noinline__ auto bench(std::string_view name, F && f, size_t setsize) {
  auto start = std::chrono::high_resolution_clock::now();
  f();
  auto tp = std::chrono::high_resolution_clock::now() - start;
  auto time = std::chrono::duration<double>{tp}.count();
  fprintf(stderr, "%s: %fsec, %fGB/s\n", name.data(), time, (setsize / double(1ul << 30)) / time);
}

int main() {
  
  fs::path path{"/dev/stdin"};
  auto size = fs::file_size(path);
  auto data = (const char *)mmap(nullptr, size + 4096, PROT_READ, MAP_PRIVATE|MAP_POPULATE, STDIN_FILENO, 0);
  sv file{data, size};
  
  auto next = [=, prev = 0ul]() mutable -> std::pair<sv, sv> {
    auto arrow_pos = file.find_first_of('>', prev);
    auto begin_pos = file.find_first_of('\n', arrow_pos);
    if(begin_pos == sv::npos) return {};
    prev = file.find_first_of('>', begin_pos);
    return {file.substr(arrow_pos, begin_pos - arrow_pos + 1), file.substr(begin_pos + 1, prev - begin_pos - 1)};
  };
  
  std::vector<std::pair<sv, sv>> index;
  for(auto pair = next(); pair != std::pair<sv, sv>{}; pair = next()) index.emplace_back(pair);
    
  
  for(auto [name, data]: index) {
    write(STDOUT_FILENO, std::data(name), std::size(name));
    bench("replace", [data = data] { replace(data); }, data.size());
  };
}
 

Есть вторая программа: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/revcomp-g...

Нужно сравнить их, собирать так(нужен буст) и gcc8.3 или новее.

g++ -Ofast -march=native -fwhole-program -std=gnu++2a -lstdc++fs main.cpp -o prog_name

Для того, что-бы забенчить - нужно взять этот код: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/fasta-gcc... Записать в fasta.c

Собрать так:

gcc -pipe -Wall -O3 -fomit-frame-pointer -march=native -fopenmp fasta.c -o fasta

Далее, нужно сделать следующие:

./fasta 100000000 > fasta_100000000.txt


time ./первая_программа 0 < fasta_100000000.txt > /dev/null

time ./вторая_программа 0 < fasta_100000000.txt > /dev/null

Запустить надо по 2-3 раза. Результаты напечатать сюда.



Последнее исправление: freddie_sadler (всего исправлений: 1)
Ответ на: комментарий от anonymous

Ты её не увидел, а случайно поймал

С чего бы это случайно? Если ты про тесты не в курсе, то сейчас самое время для тебя зауважать людей, которые тесты пишут.

anonymous
()
Ответ на: комментарий от anonymous

Эх, опять дристня полезла вместо скромной благодарности.

Ладно, надеюсь Царь в итоге победит всех в этих бенчмарках, и в этом будет в том числе немного нашей заслуги.

Deleted
()
Ответ на: комментарий от anonymous

С чего бы это случайно? Если ты про тесты не в курсе, то сейчас самое время для тебя зауважать людей, которые тесты пишут.

Случайно значит случайно. Проблема не в том как он нашел - проблема в том, что он кукарекал далее. И это у меня вызвало диссонанс, а теперь я разрешил это противоречие.

anonymous
()
Ответ на: комментарий от Deleted

Эх, опять дристня полезла вместо скромной благодарности.

За что благодарность? Состоятельную недоработку нашел аноним с тремя строками. Всё остальное - нелепая херня. Ошибку той бездарности с benchmarksgame никто так и не смог воспроизвести, а это важно. Да и ты не пытался даже.

Ты ничего не сделал. Хочешь помочь - можешь попытаться воспроизвести ошибку. Либо найти что-то состоятельное.

anonymous
()
Ответ на: комментарий от anonymous

Там (в царском блевничке), кстати, я действительно увидел без тестов, кода немного. А здесь лень читать, тупо запустил тест.

Но не будем разочаровывать Царя, пусть и дальше думает о тупых окружающих (и об умном себе)

Deleted
()
Ответ на: комментарий от Deleted

Там (в царском блевничке), кстати, я действительно увидел без тестов, кода немного. А здесь лень читать, тупо запустил тест.

Чего ты увидел, кого ты пытаешься обмануть? Твои показания не сходятся.

Если ты увидел без тестов, то значит ты увидел причину. Причина - чтение вперёд, который переходит границу файла. Если бы это знал, то ты бы не писал херню вида «падает из-за 4096 - из-за mmap - из-за stdin».

А раз ты пишешь эту херню - значит ты ничего не понял. И действительно получил ошибку случайно.

anonymous
()
Ответ на: комментарий от vertexua

Ну, если ему постоянно писать что он туповатый рукожоп, мы же не выясним, насколько это близко к истине.

А если более-менее нейтрально, только о коде - вот, пожалуйста, за несколько итераций видим более-менее внятную картину.

Deleted
()
Ответ на: комментарий от anonymous

значит ты ничего не понял

Красава, Царь. Четко раскусил. Тебя не проведешь.

Deleted
()
Ответ на: комментарий от Deleted

Повторю выше заданный вопрос. Чего ты ожидаешь в итоге, отклонений от выработанного за многие годы консенсуса? Картина и так чёткая и резкая, и внятности на ней нет сколько глаза не три.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Ну вот там выше по треду его фанат, рассказал какой царь великий учитель, спас его, наставил на путь истинный, увел от алкоголизма и С на путь познания С++.

Такими лобзаниями царь и тешит чсв

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от anonymous

Проблема не в том как он нашел

Человек просто поразмышлял о входных данных, их вариативности. А то что он цикл бахнул — это просто для наглядности. Сперва-то идёт понимание, потом реализация. У Царя же сперва идут вскукореки, потом бенчмарки, но понимания нет.

Вот тебе пример: он за каким-то хером делает стат пайпа и его размер +4к. И при этом делает mmap, вместо буфера на стеке. Спрашивается, может ли он объяснить всё это? Нет. Раст трахает плюсы у Царя на спине.

anonymous
()
Ответ на: комментарий от vertexua

Фанат?

Я знаю IRL одного фаната царя, он мне про него рассказывал ещё до того, как он почтил присутствием ЛОР. Но он был фанатом троллинга и непрошибаемости. Искренний фанат царя как просветителя - это же замечательно, это ж сразу две учетки можно за мультоводство накрыть.

t184256 ★★★★★
()
Ответ на: комментарий от anonymous

Ты решил срать из под анонима, клоун?

Человек просто поразмышлял о входных данных, их вариативности

Клоун, я выше доказал, что ты врёшь. Если ты знал о причине - ты бы не обделался в показаниях. Твои показания зафикисированы - всё.

Вот тебе пример: он за каким-то хером делает стат пайпа и его размер +4к. И при этом делает mmap, вместо буфера на стеке. Спрашивается, может ли он объяснить всё это? Нет. Раст трахает плюсы у Царя на спине.

Клоун, если ты будешь каждый раз повторять одну и ту же херню - ты думаешь, что кто-то тебе поверит? Тебе уже сообщили - никаких пайпов нет. Пайпы для бездарностей. А даже если бы это было не так - их там нету.

Но я тебе ещё раз повторю. ./prog < file - заменяет stdin на файл. Запомни это, бездарность, и не неси мне более херню. Клоун убогий.

anonymous
()
Ответ на: комментарий от anonymous

У него действительно древняя версия буста

Version: 1.67.0.1

Возможно это причина. Как же меня одалевает этот идиот. Откуда я знаю какая версия стоит в твоей убунте для домохозяек? Меня не должно это волновать.

Моя Ubuntu для домохозяек вооружена Core 2 Quad’ом и boost’ом версии 1.65.1, и у меня ничего не отваливается, программа работает исправно.

anonymous
()
Ответ на: комментарий от anonymous

Моя Ubuntu для домохозяек вооружена Core 2 Quad’ом и boost’ом версии 1.65.1, и у меня ничего не отваливается, программа работает исправно.

Ну возьми и сделай полезное дело - затести у себя.

Но давай я тебе помогу, маня. На самом деле адекватного кода в твоей убунте очень мало. И из-за таких вот поехавших люди вынуждены жрать говно, писать на говне и под говно.

По поводу буста. Тебе, домохозяйке, наверное неясно, но софт всегда должен быть актуальным. Это, кстати, особенно смешно на фоне кукаретинг клоунов про «твоя программа ненадёжна, потому, что не работает в древнем, дырявом окружении». Да, клоуны, они именно этим и надёжна. Она попросту не работает на дырявом говне - это ведь плюс.

Да вот, маня. Буст - это десятки разных либ. Я уже не помню была ли в 65 бусте хана, но скорее в сего её там не было. Т.е. у тебя попросту нету в твоём бусте говна нужных либ.

Не говоря уже о том, что в этих либах есть не починенные баги.

anonymous
()
Ответ на: комментарий от anonymous

Ну возьми и сделай полезное дело - затести у себя.

Я уже не помню была ли в 65 бусте хана, но скорее в сего её там не было. Т.е. у тебя попросту нету в твоём бусте говна нужных либ.

Я уже затестил, все скомпилировалось, ведь это я написал тебе про баг на файле из 2 строк.

anonymous
()
Ответ на: комментарий от anonymous

Но я тебе ещё раз повторю. ./prog < file - заменяет stdin на файл.

Причем тут это, фанат сосущих у раста плюсов? Ты ведь в курсе, что `wc` можно запустить по разному? Твоё говно, конечно же нет, но нормальный `wc`, например как тот, написанный на Хаскель — да. А теперь слейся уже, на ноль помноженный и не отсвечивай.

anonymous
()
Ответ на: комментарий от anonymous

Не говоря уже о том, что в этих либах есть не починенные баги.

В твоей программе тоже.

anonymous
()
Ответ на: комментарий от anonymous

На самом деле адекватного кода в твоей убунте очень мало.

Преимущество любого неидеального кода перед твоим идеальным просто — он существует и работает.

anonymous
()
Ответ на: комментарий от anonymous

Я уже затестил, все скомпилировалось, ведь это я написал тебе про баг на файле из 2 строк.

Молодец, спс. И да, в нём три строки, а не 2. Осознай уже это.

Ну т.е. ещё один человек, у которого всё работает на core2. В очередной раз мы убеждаемся, что автор это клоаки - идиот.

anonymous
()
Ответ на: комментарий от anonymous

залогинься, не позорься.

М?

Роман, ты там совсем уже что ли. Делать больше нечего, доказывать что-то интернет-дурачку с манией величия. Еще и из-под анонимуса.

Кстати, ты как вообще себя чувствуешь? Головокружение, потливость, повышенноей сердцебиение не беспокоят? Сходил бы к врачу, мало ли. А то так и не дождемся Царь-сишки и Царь-блога на крестах.

(боюсь, что даже Царь-победителя шутаута на крестах можем не дождаться, но пока отгоняю от себя эти мысли)

Deleted
()
Ответ на: комментарий от vertexua

Такими лобзаниями царь и тешит чсв

А что тебе в этом не нравится? Пусть чешит себе чсв, тебя это задевает как-то?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Ответ на: комментарий от a1batross

Цари не нужны, нужны только посредственности и унылости?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.