Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Почему std::string_view МЕДЛЕННЕЕ, чем std::string? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Ошибка C2864/C2758 http://www.cyberforum.ru/cpp-beginners/thread1754622.html
Собсна вот в чём проблема... Код писался на VS15 Community, проект был пересоздан на VS10 Ultimate Но вот беда, не хочет объявляться не статический int.. Кто сталкивался? Помогите. Ошибки на...
C++ Определить, сколько символов цифр содержит файл Извиняюсь за вопрос, но я просто не могу понять: 1) Как объяснить компилятору, что это именно число, а не буква? (предположительно через аску, но опять же как). 2) Как можно прочитать весь файл... http://www.cyberforum.ru/cpp-beginners/thread1754620.html
C++ Ошибка компиляции проекта под linux
Здраствуйте. Пытаюсь скомпилировать проект в Cygwin, получается такой лог: $ make MAKE Version 5.2 Copyright (c) 1987, 1998 Inprise Corp. gcc -c -m32 -O3 -fPIC -w -DLINUX -Wall...
C++ Умножытели: Математические операции с умножытелями
Ребята помогите написать програму до понедельника на тему: "Умножители: Математические операции с умножителями". Чесно говоря, у меня даже нет понятие ,как это делать. А у меня ещё куча работы по...
C++ Цикл с паузой http://www.cyberforum.ru/cpp-beginners/thread1754597.html
Вопрос простой до невозможности, но сколько бы я не искал его на английских форумах, на русских - нигде не нашел ответа. Как сделать цикл с паузой? sleep не работает. Что я хотел сделать - это...
C++ Ошибка error: call of overloaded Помогите разобраться с ошибкой, не хочет компилировать! ошибки не подчеркивает...)) подробнее

Показать сообщение отдельно
gromo
370 / 269 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
07.06.2016, 04:44  [ТС]
Цитата Сообщение от avgoor Посмотреть сообщение
Пока вам статья в тему: https://habrahabr.ru/post/246257/
Видел эту статейку, но у меня, к сожалению, не все так радужно, как там описано. Например, getc_unlocked временами дает худшие результаты, чем просто fread, считывающая файл одним большим блоком.

Таки как-то распараллелил я всю эту штуку.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <iomanip>
#include <unordered_set>
#include <chrono>
#include <cstdio>
#include <mutex>
#include <thread>
#include <cstring>
 
#include <experimental/string_view>
#include <experimental/filesystem>
 
 
 
namespace sc = std::chrono;
namespace fs = std::experimental::filesystem;
 
thread_local std::unordered_set<std::/*experimental::*/string/*_view*/> chunk;
std::mutex m;
std::unordered_set<std::/*experimental::*/string/*_view*/> hashSet;
 
 
void processData(const char *const data, uint32_t len)
{
    chunk.reserve(len / 4);
    const char *ptr = data, *prevPtr = data;
 
    while ( ptr = (const char*)memchr(ptr, '\n', len - (ptr-data)))
    {
        chunk.emplace((const char*)prevPtr, ptr-prevPtr);
 
        prevPtr = ++ptr;
    }
    std::lock_guard<decltype(m)> lock(m);
    hashSet.insert(chunk.cbegin(), chunk.cend());
 
}
 
int main()
{
 
    hashSet.reserve(1024*1024*2);
    const char *const fileName = "/home/z/random_values.txt";
    const auto fileSize = fs::file_size(fileName);
    const std::size_t idealThreadCount = std::thread::hardware_concurrency();
    auto buffer = std::make_unique<char[]>(fileSize);
    auto fh = std::unique_ptr<FILE, void(*)(FILE*)>(std::fopen(fileName, "rb"), [](auto *p){std::fclose(p); });
 
    std::cout << "File size: " << fileSize << " bytes\n"
              << "HW concurrency: " << idealThreadCount << std::endl;
 
    const auto start = sc::high_resolution_clock::now();
    std::fread(buffer.get(), 1, fileSize, fh.get());
 
 
    ///-------------------Multithreaded approach
    const int chunkSize = fileSize / idealThreadCount;
    std::vector<std::thread> threads;
    const char *prevPtr = buffer.get(),
               *ptr     = buffer.get(),
               *endPtr  = buffer.get() + fileSize;
 
    for(size_t threadIndex = 0; threadIndex  < idealThreadCount; ++threadIndex )
    {
 
        // If we have enough data for processing.
        if((endPtr - ptr) >= chunkSize)
        {
            ptr += chunkSize;
 
            // Find closest newline.
            while(*ptr != '\n')
                ++ptr;
        }
        else
        {
            // Process remainders of data: from last pos to the end of file.
            threads.emplace_back(processData, prevPtr, endPtr - prevPtr);
            break;
        }
 
        threads.emplace_back(processData, prevPtr, ptr  - prevPtr +1);
        prevPtr = ++ptr;
    }
 
    for(auto& thread : threads)
        thread.join();
 
 
    ///-------------------Single thread approach
//    const char* mapPtr = /*file.map(0, fileSize)*/buffer.get();
//    const char *ptr = mapPtr, *prevPtr = mapPtr;
//    while ( ptr = (const char*)memchr(ptr, '\n', fileSize - (ptr-mapPtr)))
//    {
//        hashSet.emplace((const char*)prevPtr, ptr-prevPtr);
 
//        prevPtr = ++ptr;
//    }
 
 
    // Show results.
    const auto end = sc::high_resolution_clock::now();
 
    std::cout << "+-----------------------------------------+\n"; // 43 chars
    std::cout << std::setw(25) << std::left << "|    Unique elements:"
              << "< " << hashSet.size() << " >\n"
 
              << std::setw(25) << std::left << "|    Elapsed time:"
              << "< " << sc::duration_cast<sc::milliseconds>(end-start).count()
              << "ms >" << std::endl;
    std::cout << "+-----------------------------------------+\n";
}
И в итоге (замерял сразу после перезагрузки компьютера, для чистоты):
Код
File size: 688885746 bytes
HW concurrency: 2
+-----------------------------------------+
|    Unique elements:    < 1000001 >
|    Elapsed time:       < 21097ms >
+-----------------------------------------+
Это с std::string, такой же тест на string_view упорно оставался на пару секунд медленнее. Ну и чертовщина

И вот что интересно: сразу после перезагрузки результат такой как выше. Запускаю браузер, в котором ничего не происходит ресурсоемкого, и производительность падает почти в 2 раза, до 43 секунд (т.е. хуже чем однопоточная версия!). При повторном запуске уже 30 секунд работает. От чего такие скачки? Однопоточная версия хотя бы стабильно ползала.

Добавлено через 30 минут
А вот и наш победитель на данный момент, сочетание memory mapping и мультипоточной обработки, используя std::string:
Код
File size: 688885746 bytes
HW concurrency: 2
+-----------------------------------------+
|    Unique elements:    < 1000001 >
|    Elapsed time:       < 20435ms >
+-----------------------------------------+
Что ж, неплохо, я думаю. Почти 100% прирост в производительности. Вот только Boost::Spirit я не пробовал. Может быть кто сведущий и напишет парсер простых целых чисел.

Какие будут замечания к коду по параллельной обработке ? Сам вижу, что подход топорный у меня.
0
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru