Я просто хочу написать простую программу на C++, которая создает два потока, и каждый из них заполняет вектор квадратами целых чисел (0, 1, 4, 9,. ..). Вот мой код:Многопоточная программа на C++ показывает ту же производительность, что и серийная.
#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <time.h>
#define MULTI 1
#define SIZE 10000000
void fill(std::vector<unsigned long long int> &v, size_t n)
{
for (size_t i = 0; i < n; ++i) {
v.push_back(i * i);
}
}
int main()
{
std::vector<unsigned long long int> v1, v2;
v1.reserve(SIZE);
v2.reserve(SIZE);
#if !MULTI
clock_t t = clock();
fill(v1, SIZE);
fill(v2, SIZE);
t = clock() - t;
#else
clock_t t = clock();
std::thread first(fill, std::ref(v1), SIZE);
fill(v2, SIZE);
first.join();
t = clock() - t;
#endif
std::cout << (float)t/CLOCKS_PER_SEC << std::endl;
return 0;
}
Но когда я запускаю свою программу, я вижу, что нет существенной разницы между серийной версией и параллельно один (или иногда параллельной версией показывает даже худшие результаты). Любая идея, что происходит?
Один из способов проверить, если оно ложно разделение будет иметь функцию _fill_ выполнить новый вариант создать вектор, а затем заполнить вектор, а затем возвращает указатель на вектор (возможно, с помощью параметра ссылки) , Вероятно, это исправит любой ложный обмен, который происходит, когда два потока изменяют разные данные, которые находятся в одной строке кэша. –
@Kyle Извините, этого не может быть. Я пропустил это два вектора. В любом случае 'push_back' потребуется блокировка. – LogicStuff
Программа генерирует последовательный доступ к записи в память к широко разнесенным адресам практически без использования вычислительного времени в двух потоках. Время выполнения в основном является функцией архитектуры кэша памяти оборудования. Две длинные последовательные последовательные записи, вероятно, такие же быстрые или быстрые, чем две последовательные записи чередования. – doug