【发布时间】:2020-06-05 12:54:39
【问题描述】:
我有一些昂贵的计算,我想在一组线程上进行划分和分配。 我将我的代码简化为一个仍在发生这种情况的最小示例。
简而言之:
我有 N 个任务要划分为“线程”线程。
每个任务都是运行一堆简单数学运算的以下简单函数。 (实际上我在这里验证了非对称签名,但为了简化,我排除了它)
while (i++ < 100000)
{
for (int y = 0; y < 1000; y++)
{
sqrt(y);
}
}
使用 1 个线程运行上述代码导致每次操作需要 0.36 秒(最外层的 for 循环),因此总执行时间约为 36 秒。
因此,并行化似乎是一种明显的加速方法。但是,使用两个线程时,操作时间上升到 0.72 秒,完全破坏了任何加速。
添加更多线程通常会导致性能越来越差。
我有一个 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz,有 6 个物理内核。 所以我希望至少在从 1 到 2 个线程时使用性能提升。但实际上,随着线程数的增加,每个操作都会变慢。
我是不是做错了什么?
完整代码:
using namespace std;
const size_t N = 100;
const size_t Threads = 1;
atomic_int counter(0);
struct ThreadData
{
int index;
int count;
ThreadData(const int index, const int count): index(index), count(count){};
};
void *executeSlave(void *threadarg)
{
struct ThreadData *my_data;
my_data = static_cast<ThreadData *>(threadarg);
for( int x = my_data->index; x < my_data->index + my_data->count; x++ )
{
cout << "Thread: " << my_data->index << ": " << x << endl;
clock_t start, end;
start = clock();
int i = 0;
while (i++ < 100000)
{
for (int y = 0; y < 1000; y++)
{
sqrt(y);
}
}
counter.fetch_add(1);
end = clock();
cout << end - start << ':' << CLOCKS_PER_SEC << ':' << (((float) end - start) / CLOCKS_PER_SEC)<< endl;
}
pthread_exit(NULL);
}
int main()
{
clock_t start, end;
start = clock();
pthread_t threads[Threads];
vector<ThreadData> td;
td.reserve(Threads);
int each = N / Threads;
cout << each << endl;
for (int x = 0; x < Threads; x++) {
cout << "main() : creating thread, " << x << endl;
td[x] = ThreadData(x * each, each);
int rc = pthread_create(&threads[x], NULL, executeSlave, (void *) &td[x]);
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
while (counter < N) {
std::this_thread::sleep_for(10ms);
}
end = clock();
cout << "Final:" << endl;
cout << end - start << ':' << CLOCKS_PER_SEC << ':' << (((float) end - start) / CLOCKS_PER_SEC)
<< endl;
}
【问题讨论】:
-
为什么不用
std::thread而不是pthread? -
您使用什么编译器和 C++ 标准?在现代 C++ 中,使用
pthread_t是一个很大的危险信号。 -
离题但是...您调用
td.reserve(Threads),然后使用td[x] = ...,而不会以任何方式设置向量td的大小。你的意思是resize而不是reserve? -
见这里:Incorrect Time in C++。您应该改用
std::chrono来测量经过的时间。 -
与您的问题无关,但您可能需要考虑将 while 循环替换为
for (auto& t : threads) { t.join(); }(或 pthread_join,如果您决定坚持使用 pthread)。这样你就可以摆脱丑陋的睡眠。
标签: c++ multithreading