【问题标题】:Code speed difference when using a random array index使用随机数组索引时的代码速度差异
【发布时间】:2022-06-24 21:19:08
【问题描述】:

给定 [0,1] 内的实数 X,在特定的分箱后,我必须确定 X 落在哪个箱中。给定 bin 大小 dx,我使用的是 i = std::size_t(X/dx) ,效果很好。然后我查找给定数组 v 的相应值,并使用double Y=v[i] 设置第二个变量 Y。整个代码如下:

double X = func();
dx=0.01;
int i = std::size_t(X/dx);
double Y = v[i];
print(Y)

这个方法正确地给出了索引 i 在 [0, length(v)] 范围内的期望值。

我的主要问题不是查找索引,而是使用它:X 是由辅助函数确定的,每当我需要使用上面确定的索引设置 Y=v[i] 时,代码变得非常慢。 在不注释或删除任何行的情况下,在定义后立即将 X 设置为 0 到 1 之间的某个随机值或在第三行之后将 i 设置为 0 到 v 的长度之间的某个随机值时,代码会变得更快。

谁能说出为什么会发生这种情况?速度变化 1000 倍,如果不是更多的话,而且由于在更快的方法中只有额外的步骤,并且无论如何都会调用 func(),我不明白为什么它应该变得更快。

【问题讨论】:

  • 请阅读minimal reproducible example 并尝试提供一份。没有代码,就无法判断它为什么更快/更慢
  • 在 C++ 中测量代码速度很困难,而且有很多陷阱。请告诉我们你是如何测量的。
  • 有了所有预先知道的值,就可以在编译时进行除法和转换为整数。 Y = v[42]; 会比计算 i 更快。
  • 确保在编译时启用了优化。
  • bins (v) 数组的大小是多少?

标签: c++ arrays indexing size-t


【解决方案1】:

由于您没有在问题中输入代码,因此必须有这样的猜测:

  • 在访问查找表之前,您没有对所有 X 结果进行排序。处理排序数组更快。

  • 一些 X 具有非规范化的值,这会影响某些 CPU 类型(包括您的 CPU)的计算时间。

  • 数据集对于 L3 缓存来说太大了,它总是访问 RAM,而不是在其他测试中看到的快速缓存命中。

  • 编译器正在优化所有昂贵的函数调用,但在实际测试场景中并非如此。

  • 时间测量有错误

  • 计算机的性能不稳定(例如作为共享服务器或以 RAM 带宽为食的防病毒干预)

【讨论】:

    【解决方案2】:

    原来计算 X 的过程非常缓慢,但是当添加行 X = rand(0,1) 时,优化只是初始化 X 而不调用 func()。去掉优化,两个版本的代码速度一样。感谢 Jesper 的建议。

    【讨论】:

      猜你喜欢
      • 2016-04-22
      • 1970-01-01
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      相关资源
      最近更新 更多