K& R对原始问题的答案提出问题

时间:2010-11-04 06:21:45

标签: c macros function-calls

我一直在试图解决K& R问题7-8的解决方案,直到我在这个网站上找到了this solution (with the original problem)。我无法评论答案(可能是因为它的年龄);我能在这个问题上实际输入的唯一方法是给它一个答案,我认为这是不合适的。因此,我决定根据所选择的“答案”创建这个非常相关的问题,这对我来说是合乎逻辑的,直到我达到这一点(关于将函数实现为宏):

  

“经常重复这个宏作为宏,'节省空间'迅速成为一个成本,因为位屏蔽具有固定的大小。”

唯一的问题是函数调用也需要时间。 “跳转”到功能位置,为局部变量设置存储,然后实际计算比较,所有花费时间。

那么如何实现一个宏来测试字符的ASCII值比第一个包含表查找的函数慢(考虑到这一点)?

与比较两个整数(其中一个已经在内存中,其中一个是常量)相比,函数调用可能花费的时间更少?在我看来,随着时间的推移,重复调用函数和宏仍然会导致宏更快。

我的思维方式错了吗?我想它必须是因为它没有提出原来的问题。

如果有人能对此有所了解,我会很高兴。

1 个答案:

答案 0 :(得分:3)

首先,请注意他们提到的成本是尺寸,而不是速度。例如,让我们假设宏扩展到16个字节的代码。让我们进一步假设该函数编译为32个字节的代码,并且调用该函数需要6个字节的代码(当然,这些都不是保证,但它们都可能至少在32位正确的通用球场中)码)。

在这种情况下,如果您使用一个函数,但只从一个地方调用它,那么最终会得到38个字节的代码。如果你使用宏代替你只获得16个字节的代码,节省22个字节。如果你在两个地方使用宏,你会得到32个字节的代码,如果你使用了一个函数,那么就会得到44个字节 - 仍然是节省,但是更小。稍微向前跳,我们假设您在代码中的10个不同位置使用它。在这种情况下,宏将占用160个字节,但该函数只需要92个字节。

在现代处理器上,我还可以看到一个相当合理的论点,即函数也可以更快。大多数现代处理器都使用缓存。如果您使用的功能足以让它在调用时通常会在缓存中,那么这比使用宏更快,每次使用代码时,您(更有可能)需要获取来自内存的代码。原因很简单:现代处理器比内存运行 lot 更快。

即使在最好的情况下,您也可以计划至少50 ns的延迟来从内存中获取一些数据(75-100 ns相当常见)。正如平均值假设75 ns。典型的现代CPU每时钟执行大约1.8条指令,而在(例如)2.5 GHz时,时钟周期时间为.4 ns。这意味着在75 ns内,它(平均)可以执行类似75 / 0.4 * 1.8 = 337.5指令的操作。从我们在这里谈论的函数调用,执行和返回是在六个指令的大约一个位置 - 所以在一个紧密的循环中,当你从内存中获取宏的代码时可以在大约56次的缓存中执行该功能。

当然,如果你只是在紧密循环中执行,那么宏也会在大多数时间都在缓存中。当您从代码中的足够不同的位置调用该函数时,即使在循环的第一次迭代中,它通常也会在缓存中,这种函数的优势就会发生,这通常不会是宏的情况。