C++ 如何找到C++;代码
我试图找到一个程序的效率,我最近在stackoverflow上发布了这个程序 为了比较我的代码与其他答案的效率,我使用了C++ 如何找到C++;代码,c++,algorithm,performance,chrono,C++,Algorithm,Performance,Chrono,我试图找到一个程序的效率,我最近在stackoverflow上发布了这个程序 为了比较我的代码与其他答案的效率,我使用了chronoobject 这是检查运行时效率的正确方法吗 如果没有,那么请用一个例子提出一种方法 这是检查运行时效率的正确方法吗 看来这不是最好的办法。我发现您的方法存在以下缺陷: 对值进行排序。使用相同的算法测试排序值与未排序值时,可能会暴露荒谬的效果。可能的修复方法:对已排序和未排序的结果进行测试并比较结果 值是硬编码的。CPU缓存是一个非常复杂的问题,它可能会在硬编码
chrono
object
这是检查运行时效率的正确方法吗
如果没有,那么请用一个例子提出一种方法
这是检查运行时效率的正确方法吗
看来这不是最好的办法。我发现您的方法存在以下缺陷:
- 已排序与未排序的数据
适合CPU缓存,而v3
大小超过CPU缓存。还可以考虑当<代码>(V1.LINTHORE)+V3.LINGHOTH()INTIZEOF(INT)适合缓存时,<代码>(V1.LINTHOTE)+V2.LINTHOST(+)+V3.LINTHOST()> SIZEOF(INT)适合缓存或不适合所有组合。v3
您的方法的最大问题是: 1)您正在测试的代码太短,无法预测。您需要至少运行它几千次,以便在测量之间至少有几百毫秒。您需要使数据集更大,更不可预测。一般来说,CPU缓存确实能够根据PITA中的合成输入数据进行精确的测量 2)编译器可以自由地对代码重新排序。一般来说,很难确保正在计时的代码在两次调用之间执行以检查时间(除此之外,没有其他事情)。一方面,您可以进行向下优化,但另一方面,您希望度量优化的代码 一种解决方案是关闭整个程序优化,并将计时调用放在另一个编译单元中 另一个可能的解决方案是在测试周围使用内存围栏,例如
std::atomic_thread_fence(std::memory_order_seq_cst);
(需要#包括和一个支持C++11的编译器)
此外,您可能希望使用探查器数据补充测量数据,以查看L1/2/3缓存的使用效率、内存瓶颈、指令失效率等。不幸的是,英特尔x86的最佳工具是商用(vtune),但在AMD x86上,类似的工具是免费的(codeXL) 您可以考虑使用基准测试库来为您量度测量值,并处理性能测量的棘手部分,而您仍然专注于试图优化的代码。更复杂的示例可以在我在前面问题()的答案中链接的代码中找到,但是一个简单的用例如下所示:
BENCHMARK(VectorRemoval, OriginalQuestion, 100, 1000)
{
std::vector destination(10000);
std::generate(destination.begin(), destination.end(), std::rand);
std::sample(destination.begin(), destination.end(), std::back_inserter(source),
100, std::mt19937{std::random_device{}()})
for (auto i: source)
destination.erase(std::remove(destination.begin(), destination.end(), i),
destination.end());
}
阅读这篇文章,了解如何对chrono
调用重新排序,从而使测量结果无效。我认为多次执行同一代码会得到更好的结果,然后得到平均值。要进行正确的度量,至少需要做三件事:1)预热(在度量之前做许多类似的操作),2)找到多次调用的平均结果,3)避免编译器的过度优化(如果它可以检测到您不使用计算结果,它可以跳过它)性能测量并不容易。考虑使用一个库,这样就可以很容易地得到正确的结果。侵入性测量框架在实际测量性能方面是行不通的。你应该使用一种非侵入性的工具,如Linux PiF或英特尔VTUNE来实际测量实际性能,而不可能妨碍编译。你关于笛卡尔积使用的注释非常好。一个很好的链接可能是。请记住,一个CPU中有多个缓存。一级缓存大约为128kb,需要32000多个元素来填充缓存。二级CPU缓存的大小为1MB,您需要列表中超过25万个元素来打破缓存大小。打破8MB大小的三级缓存,看看外挂到RAM对性能的影响,这可能也很有趣。
std::atomic_thread_fence(std::memory_order_seq_cst);
BENCHMARK(VectorRemoval, OriginalQuestion, 100, 1000)
{
std::vector destination(10000);
std::generate(destination.begin(), destination.end(), std::rand);
std::sample(destination.begin(), destination.end(), std::back_inserter(source),
100, std::mt19937{std::random_device{}()})
for (auto i: source)
destination.erase(std::remove(destination.begin(), destination.end(), i),
destination.end());
}