限制指针和内联

时间:2012-07-15 20:40:07

标签: c++ visual-studio-2010 optimization restrict-qualifier

我试过使用限制合格的指针,但我遇到了一个问题。 下面的程序只是一个简单的程序,只是为了解决这个问题。

calc_function使用三个指针,这些指针受到限制,因此它们“SHALL”不会相互别名。在visual studio中编译此代码时,该函数将被内联,因此Visual Studio 2010无缘无故忽略限定符。如果我禁用内联,代码执行速度会快6倍(从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;
}

1 个答案:

答案 0 :(得分:3)

如果使用__declspec(noinline)声明一个函数,它将强制它不被内联:

http://msdn.microsoft.com/en-us/library/kxybs02x%28v=vs.80%29.aspx

您可以使用此功能手动禁用每个功能的内联。


对于restrict,编译器只有在需要时才可以自由使用它。因此,当试图“欺骗”编译器进行这样的优化时,摆弄同一代码的不同版本是不可避免的。