我们有一个任务,我们得到了一个效率非常低的程序,我们必须优化代码以使其运行得更快。我已经让他们中的大多数人运行得非常快,除了这两个,这让我非常烦恼,因为它们是非常简单的功能。一种基本上将二维数组中的所有值设置为相同的值,另一种基本上交换两个二维数组的值。这就是问题所在。它们占用的时间最多,但由于它们非常简单,我无法弄清楚如何在不破坏功能的情况下减少它们。而且我知道让他们跑得更快是可能的,因为班上的其他学生已经获得了可笑的加速。有问题的两个是:
fSetArray(int rows, int cols, float val)
{
int i, j;
F2D *out;
out = fMallocHandle(rows, cols);
for(i=0; i<rows; i++)
for(j=0; j<cols; j++)
subsref(out,i,j) = val;
return out;
}
唯一重要的部分是那里的两个循环。基本上,我们有一个具有一定宽度(行)和一定高度(列)的二维数组,我们将所有值设置为 val。但是我看不到消除其中一个循环的方法(这将是加速它的最佳方法)。除非我遗漏了一些明显的东西。如果 cols 和 rows 是相同的数字,这会容易得多。
另一个功能是:
fDeepCopy(F2D* in)
{
int i, j;
F2D* out;
int rows, cols;
rows = in->height;
cols = in->width;
out = fMallocHandle(rows, cols);
for(i=0; i<rows; i++)
for(j=0; j<cols; j++)
subsref(out,i,j) = subsref(in,i,j);
return out;
}
out 数组总是比 in 数组大,所以我们不必担心溢出等问题。这个函数基本上只是交换两个数组的值,但是再一次,因为它太简单了,我不能让它进一步减少。
在任何人说并行化之前,由于样本大小和服务器,创建线程所需的开销实际上会减慢程序的速度。我试过了。因为这两个函数太短了,所以不值得创建线程只在一次并行后杀死它们。
但是作为参考,从技术上讲,这是一个 OpenMP 项目,我们应该使用并行化,但是对于这两个功能,这样做实际上会减慢整个程序的速度。我已经用一个并行的 for 循环来检查它。
编辑:感谢所有给我想法的人!我现在已经启动并运行并全速运行!