同时使用多个线程c ++
using multiple threads simultaneously c++
我在为我的 madelbrot 程序使用多线程时遇到问题。
我厌倦了遵循教程的方式之一
int sliceSize = 800 / threads;
double start = 0, end = 0;
for (int i = 0; i < threads; i++)
{
start = i * sliceSize;
end = ((1 + i) * sliceSize);
thrd.push_back(thread(compute_mandelbrot, left, right, top, bottom, start, end));
}
for (int i = 0; i < threads; i++)
{
thrd[i].join();
}
thrd.clear();
但是代码只需要一半的时间来计算,同时使用 8 个线程。
我也尝试了一些更复杂的方法,但根本不起作用
void slicer(double left, double right, double top, double bottom)
{
/*promise<int> prom;
future<int> fut = prom.get_future();*/
int test = -1;
double start = 0, end = 0;
const size_t nthreads = std::thread::hardware_concurrency(); //detect how many threads cpu has
{
int sliceSize = 800 / nthreads;
std::cout << "CPU has " << nthreads << " threads" << std::endl;
std::vector<std::thread> threads(nthreads);
for (int t = 0; t < nthreads; t++)
{
threads[t] = std::thread(std::bind(
[&]()
{
mutex2.lock();
test++;
start = (test) * sliceSize;
end = ((test + 1) * sliceSize);
mutex2.unlock();
compute_mandelbrot(left, right, top, bottom, start, end);
}));
}
std::for_each(threads.begin(), threads.end(), [](std::thread& x) {x.join(); }); //join threads
}
}
但它似乎同时计算 8 个东西,即使在使用互斥锁后它们也倾向于重叠,而且速度也没有任何提高。
这让我头疼了 7 个小时,我想自杀。帮助。
当您尝试通过多线程加速工作负载时,有很多因素在起作用,在完美的世界中,乘以 N 线程时几乎不可能获得 Nx 加速。一些注意事项:
- 如果您正在使用超线程(因此系统上的每个虚拟核心使用 1 个线程,而不仅仅是每个物理核心),那么您将无法获得与 2 个真实核心相同的性能 - 您将获得一些百分比(可能在 1.2 倍左右)。
- 操作系统 (Windows) 将在您的工作负载执行时执行某些操作。这些 OS 任务在什么时候以及什么时候占用您的应用程序时间是相当随机的,但这会有所作为。总是期望你的 CPU 时间的一部分会被 windows.
偷走
- 任何类型的同步都会严重影响性能。在您的第二个示例中,互斥量非常大,可能会影响性能。
- 内存访问、缓存访问等将发挥作用。多个线程到处访问内存将导致缓存压力,这将产生(潜在)影响。
我很好奇 - 你在看什么时代?您在每个线程上传递了多少次迭代?要深入了解并按时序查看发生了什么,您可以尝试使用 queryPerformanceCounter 记录每个线程的 start/end 时间,以查看每个线程 运行 的时长,它们何时开始等。发布时间这里的 1、2、4 和 8 个线程可能会有所启发。
希望这至少能有所帮助...
我在为我的 madelbrot 程序使用多线程时遇到问题。
我厌倦了遵循教程的方式之一
int sliceSize = 800 / threads;
double start = 0, end = 0;
for (int i = 0; i < threads; i++)
{
start = i * sliceSize;
end = ((1 + i) * sliceSize);
thrd.push_back(thread(compute_mandelbrot, left, right, top, bottom, start, end));
}
for (int i = 0; i < threads; i++)
{
thrd[i].join();
}
thrd.clear();
但是代码只需要一半的时间来计算,同时使用 8 个线程。
我也尝试了一些更复杂的方法,但根本不起作用
void slicer(double left, double right, double top, double bottom)
{
/*promise<int> prom;
future<int> fut = prom.get_future();*/
int test = -1;
double start = 0, end = 0;
const size_t nthreads = std::thread::hardware_concurrency(); //detect how many threads cpu has
{
int sliceSize = 800 / nthreads;
std::cout << "CPU has " << nthreads << " threads" << std::endl;
std::vector<std::thread> threads(nthreads);
for (int t = 0; t < nthreads; t++)
{
threads[t] = std::thread(std::bind(
[&]()
{
mutex2.lock();
test++;
start = (test) * sliceSize;
end = ((test + 1) * sliceSize);
mutex2.unlock();
compute_mandelbrot(left, right, top, bottom, start, end);
}));
}
std::for_each(threads.begin(), threads.end(), [](std::thread& x) {x.join(); }); //join threads
}
}
但它似乎同时计算 8 个东西,即使在使用互斥锁后它们也倾向于重叠,而且速度也没有任何提高。
这让我头疼了 7 个小时,我想自杀。帮助。
当您尝试通过多线程加速工作负载时,有很多因素在起作用,在完美的世界中,乘以 N 线程时几乎不可能获得 Nx 加速。一些注意事项:
- 如果您正在使用超线程(因此系统上的每个虚拟核心使用 1 个线程,而不仅仅是每个物理核心),那么您将无法获得与 2 个真实核心相同的性能 - 您将获得一些百分比(可能在 1.2 倍左右)。
- 操作系统 (Windows) 将在您的工作负载执行时执行某些操作。这些 OS 任务在什么时候以及什么时候占用您的应用程序时间是相当随机的,但这会有所作为。总是期望你的 CPU 时间的一部分会被 windows. 偷走
- 任何类型的同步都会严重影响性能。在您的第二个示例中,互斥量非常大,可能会影响性能。
- 内存访问、缓存访问等将发挥作用。多个线程到处访问内存将导致缓存压力,这将产生(潜在)影响。
我很好奇 - 你在看什么时代?您在每个线程上传递了多少次迭代?要深入了解并按时序查看发生了什么,您可以尝试使用 queryPerformanceCounter 记录每个线程的 start/end 时间,以查看每个线程 运行 的时长,它们何时开始等。发布时间这里的 1、2、4 和 8 个线程可能会有所启发。
希望这至少能有所帮助...