Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
控制GCC优化_C_Assembly - Fatal编程技术网

控制GCC优化

控制GCC优化,c,assembly,C,Assembly,我正在尝试测试我有权访问的机器的缓存属性。为了做到这一点,我试图读取内存并计时。我改变工作集大小和步幅访问模式以获得不同的测量值 代码如下所示: clock1 = get_ticks() for (i = 0; i < 1000000; i++) { for (j = 0; j < (workingset * stride / sizeof(data_t)); j += stride) { *array[j]; } } clock2 = get_ticks() cl

我正在尝试测试我有权访问的机器的缓存属性。为了做到这一点,我试图读取内存并计时。我改变工作集大小和步幅访问模式以获得不同的测量值

代码如下所示:

clock1 = get_ticks()
for (i = 0; i < 1000000; i++) {
  for (j = 0; j < (workingset * stride / sizeof(data_t)); j += stride) {
    *array[j];
  }
}
clock2 = get_ticks()
clock1=get_ticks()
对于(i=0;i<1000000;i++){
对于(j=0;j<(工作集*步幅/sizeof(数据));j+=步幅){
*数组[j];
}
}
时钟2=获取时钟信号()

现在的问题是,有了合理的优化级别,gcc将优化读取,因为它没有副作用。我不能没有优化级别,否则所有的循环变量都会导致读取内存。我尝试过一些不同的方法,比如使数组易失性,以及使用转换为易失性的内联函数,但是gcc对易失性变量的处理很难预测。执行此操作的适当方法是什么?

一种可能是以不易优化的方式使用阵列数据,例如:

clock1 = get_ticks();
sum = 0;
for (i = 0; i < 1000000; i++) {
  for (j = 0; j < (workingset * stride / sizeof(data_t)); j += stride) {
    sum += array[j];
  }
}
clock2 = get_ticks();
return sum;
clock1=get_ticks();
总和=0;
对于(i=0;i<1000000;i++){
对于(j=0;j<(工作集*步幅/sizeof(数据));j+=步幅){
总和+=数组[j];
}
}
时钟2=获取时钟信号();
回报金额;
sum
应该在寄存器中,并且add操作不应该对循环计时添加任何重要内容


如果测试函数和调用者都在同一个编译单元中,您可能还需要确保对返回的和值执行某些操作,例如,通过printf输出它。

对于GCC,请尝试为所有索引变量(
i
j
)指定使用的
,以避免编译器对它们进行优化(即使启用了全局优化选项):

inti_uuu属性_uuu((使用));
int j_uuu属性_uuu((使用));
时钟1=获取时钟信号()
对于(i=0;i<1000000;i++){
对于(j=0;j<(工作集*步幅/sizeof(数据));j+=步幅){
*数组[j];
asm(“”;//有助于避免循环体消除
}
}
时钟2=获取时钟信号();

同样值得一提的是,
asm(…)
表达式从来没有被优化过。你甚至可以在没有任何汇编表达式的情况下使用它,比如:
asm(“”;

如果你不想让编译器对它进行模糊处理,我认为你应该尝试在汇编中编写它。你不能保证有任何“技巧”将永远有效。现在有效的东西可能会在未来版本的编译器中进行优化。此外,可能很难预测它是否有效。如果您能够检查汇编代码以查看它是否有效(即,没有对其进行优化),您也应该能够从头开始写入它?

在每次迭代时将值存储到
volatile
全局变量。这将确保实际写入发生(例如,这对于确保在信号处理程序中看到正确的值是必要的)

或者,使用类似

sum += *array[j]^i;

这很容易计算,但可以确保编译器无法使用求和公式轻松优化out循环。

GCC将对其进行优化。例如,GCC只需将内部循环运行一次后的sum值乘以1000000,它就正确了。@dschatz:您可能需要确保对返回的su执行某些操作m值,例如,通过printf输出。输出它无论如何都不重要,它可以优化两个循环并获得值。@dschatz:好的-我现在看到了问题-我正在考虑另一种优化方法。我认为您可能需要使数组同时具有全局性和易失性。@dschatz:如果数组是易失性的,则无法对其进行优化。不确定是否可行这是:编译成汇编程序,无需优化,你想要计时的代码,然后用
asm{}
块替换C代码,编译整个程序包括一些缓存属性的基准测试。开玩笑:确保循环计算开放式数学问题的解决方案,以便编译器无法对其进行优化:
sum += *array[j]^i;