- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 C 编写一个程序,其中有几个常量我希望我的所有函数都使用。到目前为止,我已经使用了宏。该程序的简化版本如下所示。
#define CONSTANT 10 //int
int multiplication_by_constant(int a){ return a*CONSTANT;}
int main(){
for(int i = 1; i< 10; i++)
printf("%d\n",multiplication_by_constant(i));
}
现在我想通过使用不同的常量值多次运行程序来对程序进行实验。我想自动执行此操作,而不是每次更改 CONSTANT 时都重新编译。我使用了一个简单的解决方案,将宏更改为全局变量,将原始主函数放入新的“program()”函数中,然后在主文件中运行实验,即
int CONSTANT = 10; //int
int multiplication_by_constant(int a){ return a*CONSTANT;}
void program(){
for(int i = 1; i< 10; i++)
printf("%d\n",multiplication_by_constant(i));
}
int main(){
while(CONSTANT < 100){
program();
}
return 0;
}
我发现这个实现会导致循环性能的大幅下降
for(int i = 1; i< 10; i++)
printf("%d\n",multiplication_by_constant(i));
现在需要比我使用宏时多 50% 的运行时间。这是正常的吗?
任何人都可以建议一种更有效的方法来运行我的实验吗?
PS 在 C++ 中,我会通过定义“类程序”、将 CONSTANT 设置为类成员并将“multiplication_by_constant”设置为成员函数来实现。然后我可以使用类定义轻松地通过“main”运行实验,我想我不会有效率损失......我必须在这个实现中使用 C 这就是为什么我求助于全局变量和功能。
最佳答案
好吧,这是性能差异的潜在来源。对于宏,CONSTANT
的值在编译时 是已知的,因此编译器可以利用该知识并以稍微不同的方式构造机器代码。我对您的代码进行了修改,并使用 gcc -Wa,-aldh
为宏版本和全局变量版本获取了汇编列表1,其中有一个有趣的区别。
首先是宏版本:
3 .globl mul_by_const
5 mul_by_const:
6 .LFB2:
7 0000 55 pushq %rbp
8 .LCFI0:
9 0001 4889E5 movq %rsp, %rbp
10 .LCFI1:
11 0004 897DFC movl %edi, -4(%rbp)
12 0007 8B55FC movl -4(%rbp), %edx
13 000a 89D0 movl %edx, %eax<em><strong>
14 000c C1E002 sall $2, %eax
15 000f 01D0 addl %edx, %eax
16 0011 01C0 addl %eax, %eax</strong></em>
17 0013 C9 leave
18 0014 C3 ret
突出显示的行是函数的核心;该函数不是将 %eax
中的值乘以 10,而是先算术左移 2 位,然后进行加法(有效地乘以 5),然后将结果与自身相加。例如,给定 3
的 i
值:
3 << 2 == 12
3 + 12 == 15
15 + 15 == 30
如果您更改CONSTANT
的值,编译器将生成不同的机器代码(CONSTANT
值为7
会导致算术移位左移 3 后跟减法,而 19
的值左移 3 后跟 3 加法,等等)。
与全局变量版本比较:
2 .globl CONSTANT
3 .data
4 .align 4
7 CONSTANT:
8 0000 0A000000 .long 10
9 .text
10 .globl mul_by_const
12 mul_by_const:
13 .LFB2:
14 0000 55 pushq %rbp
15 .LCFI0:
16 0001 4889E5 movq %rsp, %rbp
17 .LCFI1:
18 0004 897DFC movl %edi, -4(%rbp)
19 0007 8B050000 movl CONSTANT(%rip), %eax
19 0000<strong><em>
20 000d 0FAF45FC imull -4(%rbp), %eax</em></strong>
21 0011 C9 leave
22 0012 C3 ret
此版本使用 imull
操作码进行乘法运算。由于 CONSTANT
的值在编译时未知,因此编译器无法根据该值进行任何特殊优化。
现在,这就是我的特定平台上的情况;我不知道你使用的是什么编译器或者你运行的是什么操作系统,所以你得到的机器代码很可能与我上面的不同。我只是指出在编译时知道 CONSTANT
允许编译器做一些额外的优化。
编辑
如果您更改宏的值,您必须重新编译。你可以把宏放在头文件中,然后写一个脚本来重新生成头文件并重新编译,就像
#!/bin/bash
let CONSTANT=1
while [ $CONSTANT -lt 20 ]
do
cat > const.h << EOF
#ifndef CONST_H
#define CONST_H
#define CONSTANT $CONSTANT
#endif
EOF
# build and run your test code, assuming profiling is captured
# automatically
gcc -o test test.c
./test
let CONSTANT=CONSTANT+1
done
并且您的 C 代码将 #include
const.h 文件:
#include "const.h"
int multiplication_by_constant(int a){ return a*CONSTANT;}
...
关于c - 在 C 语言中,宏是否比全局变量运行得更快?如何在运行之间更改宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30403270/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How to nest OR statements in JavaScript? 有没有办法做到这一点:
在 JavaScript 中有没有办法让一个变量总是等于一个变量?喜欢var1 = var2但是当var2更新,也是var1 . 例子 var var1 = document.getElementBy
我正在努力理解这代表什么 var1 = var2 == var3 我的猜测是这等同于: if (var2 == var3): var1 = var2 最佳答案 赋值 var1 = var2
这个问题已经有答案了: What does the PHP error message "Notice: Use of undefined constant" mean? (2 个回答) 已关闭 8
我在临时表中有几条记录,我想从每条记录中获取一个值并将其添加到一个变量中,例如 color | caption -------------------------------- re
如何将字符串转为变量(字符串变量--> $variable)? 或者用逗号分隔的变量列表然后转换为实际变量。 我有 2 个文件: 列名文件 行文件 我需要根据字符串匹配行文件中的整行,并根据列名文件命
我有一个我无法解决的基本 php 问题,我也想了解为什么! $upperValueCB = 10; $passNodeMatrixSource = 'CB'; $topValue= '$uppe
这可能吗? php $variable = $variable1 || $variable2? 如果 $variable1 为空则使用 $variable2 是否存在类似的东西? 最佳答案 PHP 5
在 Perl 5.20 中,for 循环似乎能够修改模块作用域的变量,但不能修改父作用域中的词法变量。 #!/usr/bin/env perl use strict; use warnings; ou
为什么这不起作用: var variable; variable = variable.concat(variable2); $('#lunk').append(variable) 我无法弄清楚这一点
根据我的理解,在32位机器上,指针的sizeof是32位(4字节),而在64位机器上,它是8字节。无论它们指向什么数据类型,它们都有固定的大小。我的计算机在 64 位上运行,但是当我打印包含 * 的大
例如: int a = 10; a += 1.5; 这运行得很完美,但是 a = a+1.5; 此作业表示类型不匹配:无法从 double 转换为 int。所以我的问题是:+= 运算符 和= 运算符
您好,我写了这个 MySQL 存储过程,但我一直收到这个语法错误 #1064 - You have an error in your SQL syntax; check the manual that
我试图在我的场景中显示特定的奖牌,这取决于你的高分是基于关卡的目标。 // Get Medal Colour if levelHighscore goalScore { sc
我必须维护相当古老的 Visual C++ 源代码的大型代码库。我发现代码如下: bIsOk = !!m_ptr->isOpen(some Parameters) bIsOk的数据类型是bool,is
我有一个从 MySQL 数据库中提取的动态产品列表。在 list 上有一个立即联系 按钮,我正在使用一个 jquery Modal 脚本,它会弹出一个表单。 我的问题是尝试将产品信息变量传递给该弹出窗
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
jQuery Core Style Guidelines建议两种不同的方法来检查变量是否已定义。 全局变量:typeof variable === "undefined" 局部变量:variable
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: “Variable” Variables in Javascript? 我想肯定有一种方法可以在 JavaScrip
在语句中使用多重赋值有什么优点或缺点吗?在简单的例子中 var1 = var2 = true; 赋值是从右到左的(我相信 C# 中的所有赋值都是如此,而且可能是 Java,尽管我没有检查后者)。但是,
我是一名优秀的程序员,十分优秀!