游戏"Life"中发布和调试版本之间的加速比例奇怪
Strange ratio in speedup between release and debug builds in game "Life"
我与四面邻居一起写了经典游戏"生活"。当我在 debug 中运行它时,它说:
- 连续版本:4.2S
- 并行版本:1.5S
okey,很好。但是,如果我在版本中运行,它说:
- 连续版本:0.46S
- 并行版本: 1.23S
为什么?我用4个内核在计算机上运行它。我在并行部分中运行4个线程。答案是正确的。但是Somethere是泄漏的,我不知道那个地方。有人可以帮我吗?
我尝试在Visual Studio 2008和2012中运行它。结果是相同的。OMP已在项目设置中启用。
要重复我的问题,您可以找到定义的常数PARALLEL
并将其设置为1或0,以相应地启用和禁用OMP。答案将在out.txt
中(out.txt-正确的答案示例)。输入必须在in.txt中(我的输入 - in.txt)。有一些俄罗斯符号,您不需要理解它们,但是in.txt
中的第一个数字是指在平行部分中运行的线程数(示例中是4
)。
主要部分放置在StartSimulation
功能中。如果运行该程序,您将在控制台中看到一些带有运行时间的俄罗斯文字。
程序代码足够大,所以我将其添加到文件托管-Main.cpp(L2为我表示"实验2")
有关StartSimulation
功能的一些评论。我将用细胞切成小矩形的2D表面。它是由AdjustKernelsParameters
函数完成的。
我没有发现比率那么奇怪。拥有多个线程合作是一项复杂的业务,并具有开销。
需要序列化对共享内存的访问,这通常涉及某种形式的锁定机制和线程之间必须等待锁定锁定的线程之间的争夺。这种共享变量需要在处理器内核之间同步,这可以带来重大放缓。同样,编译器需要将这些关键领域视为"序列点"。
所有这些都降低了处理器硬件中的每个线程优化的范围和每个线程与共享变量一起工作时的编译器。
在这种情况下,并行化的开销似乎超过了单线外壳的优化可能性。
如果每个线程在访问共享变量之前需要独立进行更多的工作,那么这些间接费用将不那么重要。
您正在使用guided
循环时间表。考虑到您正在处理一个常规问题,这是一个非常糟糕的选择,如果将域简单地分为相等大小的块,则每个任务都可以轻松地完成与其他任何任务完全相同的工作。
用schedule(static)
替换schedule(guided)
。还可以通过livingCount
减少总和,而不是使用锁定增量:
#if PARALLEL == 1
#pragma omp parallel for schedule(static) num_threads(kernelsCount)
reduction(+:livingCount)
#endif
for (int offsetI = 0; offsetI < n; offsetI += kernelPartSizeN)
{
for (int offsetJ = 0; offsetJ < m; offsetJ += kernelPartSizeM)
{
int boundsN = min(kernelPartSizeN, n - offsetI),
boundsM = min(kernelPartSizeM, m - offsetJ);
for (int kernelOffsetI = 0; kernelOffsetI < boundsN; ++kernelOffsetI)
{
for (int kernelOffsetJ = 0; kernelOffsetJ < boundsM; ++kernelOffsetJ)
{
if(BirthCell(offsetI + kernelOffsetI, offsetJ + kernelOffsetJ))
{
++livingCount;
}
}
}
}
}
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 为什么加载SDF会导致Mobilizer创建闭环错误
- OpenCV 3.4 C++ Cuda 加速比 CPU 花费更多时间
- 加载/存储8位和32位之间的值
- 什么可能导致时间函数和 DLL 加载之间死锁
- 抵消内存中加载的 DLL 与硬盘上的 DLL 之间的不匹配
- 显式原子加载/存储与常用运算符=和运算符T之间的区别是什么