限制指针和内联
我试图使用限制合格的指针,我遇到了一个问题。 下面的程序仅仅是一个简单的问题。
calc_function使用三个指针,这些指针是受限制的,因此它们“应该”不会彼此混淆。 在Visual Studio中编译此代码时,该函数将被内联,因此无论如何,Visual Studio 2010都会忽略限定符。 如果我禁用内联,代码执行速度会提高六倍(从2200ms到360ms)。 但我不想在整个项目中禁用内联,也不想在整个文件中禁用内联(因为那样会在例如所有getter和setter中调用开销,这会很糟糕)。
(可能唯一的解决方案是禁用内联仅此功能?)
我试图在函数中创建临时限制限定指针,在顶部和内部循环中试图告诉编译器,我保证没有别名,但编译器不会相信我,也不会工作。 我也试图调整编译器设置,但唯一一个我发现的工作,是禁用内联。
我希望有一些帮助来解决这个优化问题。
要运行该程序(在realeasemode中),请不要忘记使用参数0 1000 2000.为什么使用userinput / program参数是为了确保编译器无法知道指针之间是否存在别名a,b和c。
#include <cstdlib>
#include <cstdio>
#include <ctime>
// Data-table where a,b,c will point into, so the compiler cant know if they alias.
const size_t listSize = 10000;
int data[listSize];
//void calc_function(int * a, int * b, int * c){
void calc_function(int *__restrict a, int *__restrict b, int *__restrict c){
for(size_t y=0; y<1000*1000; ++y){ // <- Extra loop to be able to messure the time.
for(size_t i=0; i<1000; ++i){
*a += *b;
*c += *a;
}
}
}
int main(int argc, char *argv[]){ // argv SHALL be "0 1000 2000" (with no quotes)
// init
for(size_t i=0; i<listSize; ++i)
data[i] = i;
// get a, b and c from argv(0,1000,2000)
int *a,*b,*c;
sscanf(argv[1],"%d",&a);
sscanf(argv[2],"%d",&b);
sscanf(argv[3],"%d",&c);
a = data + int(a); // a, b and c will (after the specified argv) be,
b = data + int(b); // a = &data[0], b = &data[1000], c = &data[2000],
c = data + int(c); // So they will not alias, and the compiler cant know.
// calculate and take time
time_t start = clock();
funcResticted(a,b,c);
time_t end = clock();
time_t t = (end-start);
printf("funcResticted %u (microSec)n", t);
system("PAUSE");
return EXIT_SUCCESS;
}
如果使用__declspec(noinline)
声明函数,将强制它不被内联:
http://msdn.microsoft.com/en-us/library/kxybs02x%28v=vs.80%29.aspx
您可以使用此功能在每个功能的基础上手动禁用内联。
至于restrict
,编译器只有在需要时才可以使用它。 所以试图“欺骗”编译器来做这种优化时,摆弄不同版本的相同代码是不可避免的。
上一篇: Restrict pointers and inlining
下一篇: Histogram of Oriented Gradients vs Edge Orientation Histograms