c - 在 for 循环中使用变量作为数组的索引而不是在每次迭代时计算它们真的更快吗?
问题描述
在我的实习期间,我必须使用嵌套的 for 循环,我写了这样的东西(在 C 中):
for (int N_dt0_s_dt = 0; N_dt0_s_dt < N_dt; N_dt0_s_dt++)
{
for (int j = 0; j < N; j++)
{
for (int i = 0; i < N0; i++)
{
Matrix_t0[i + N0 * j] += M_t_t0_loc[i + N0 *(N_dt0_s_dt + j)];
}
}
}
这里,N 和 N0 是表示矩阵维数的整数。N 和 N0 介于 200 和 500 之间,具体取决于输入矩阵。在审查代码期间,一些同事建议进行以下更改:
int dec,dec1;//to compute index
for (int N_dt0_s_dt = 0; N_dt0_s_dt < N_dt; N_dt0_s_dt++)
{
for (int j = 0; j < N; j++)
{
dec = N0 * j;
dec1 = N0 *(N_dt0_s_dt + j);
for (int i = 0; i < N0; i++)
{
Matrix_t0[i + dec] += M_t_t0_loc[i + dec1];
}
}
}
}
同事告诉我,后者应该运行得更快,因为我们没有计算每次迭代时得出 N0 *(N_dt0_s_dt + j) 所需的操作。
我认为这是非常合理的,但我在问自己编译器(Visual Studio)是否已经在进行优化,这会使这些更改变得无用。
对此的一些想法将不胜感激。
解决方案
您需要查看生成的组件以确定。也就是说,通用子表达式消除是一种非常容易理解的优化技术,据我所知,现在大多数常用的编译器都会使用合适的优化选项来实现。
有趣的是,优化人员如今的工作越来越好。过去,如果您写下以下内容,您会得到一记耳光:
for (auto it = container.begin(); it != container.end(); it++)
但是,我通过编写两个等效函数来测试 MSVC,其中一个使用上述函数,而另一个使用“已批准”:
for (auto it = container.begin(); it != container.end(); ++it)
没有其他区别。
MSVC 不仅正确地意识到它可以替换it++
为,++it
因为我实际上并没有使用该值,然后它在链接过程中注意到这两个例程现在是相同的,所以它完全省略了其中一个,并使用了目标代码另一个用于两个调用。
推荐阅读
- python - 为什么 numpy max 函数(np.max)返回错误的输出?
- amazon-web-services - 如何修复 terraform 中标签的属性值类型错误?
- web-services - 如何启用对托管在 GCP VM 实例上的 Web 服务的访问
- php - Projet laravel / vuejs 从 linux 到 windows
- actions-on-google - 如何在@assistant/conversation 中关闭对话
- bash - 将 shell 脚本中的变量用于 gnuplot
- python - 在python中将字符串转换为函数名
- c# - 单个文件发布不适用于 WPF 应用程序
- swift - 在 tvOS Swift 中实时流式传输 JPEG 图像
- css - Rails 简单表单:将字体真棒图标移动到输入字段旁边