簡體   English   中英

有關C ++中的函數調用和評估的問題

[英]A question about function call and evaluation in C++

嘿,關於以下問題,我可能有一個直截了當的問題:

我有一個功能

double afunction(double *myarray)
{   
    double ret = 1.0;
    for(int i = 0; i < 4; i++)
        ret *= myarray[i]*myarray[i];
    return ret;
}

現在我想,這樣我通過兩個新的參數進行修改: int index描述的,其索引myarray改變如下所示: myarray[ index ] = *add; 這將是以下內容:

double afunction(double *myarray, int index, double *add)
{   
    myarray[ index ] += *add;
    double ret = 1.0;
    for(int i = 0; i < 4; i++)
        ret *= myarray[i]*myarray[i];
    return ret;
}

問題是:由於內存方面的myrray ,我不想修改數組myrray也不想為此創建一個新數組 (稍后將在GPU上進行計算,因此我無法分配整個數組還是在內核函數中添加了新數組,對此的簡單解決方案?

編輯抱歉,我輸錯了什么。 相反, myarray[ index ] = *add; 我的意思是說myarray[ index ] += *add;

EDIT2較大函數的示例,以后可以輕松擴展到大約50種不同的返回情況。 因此,要讓if語句在每個返回案例中添加*add來修改特定值myarray[index] ,是很丑陋的:(

double afunction(double *myarray, int funcIndex, int indexAdd, double *add)
{   
    myarray[ indexAdd ] += *add;

    if(funcIndex >= 1 && funcIndex <= 4)
        return myarray[1]*myarray[1]*myarray[2];

    switch(funcIndex)
    {
        case 5:
            return sin(myarray[3]) * cos(myarray[1]);
        case 6:
            double ret = exp(myarray[1]);
            for(int i = 1; i < 5; i++)
                ret *= (myarray[ i ]-myarray[ 5-i ]);
            return ret;
        case 7:
            double ret = 0.0;
            for(int i = 1; i < 10; i++)
                ret += myarray[ i ];
            return ret;
    }

    return 0.0;
}
double ret = 1.0;
for(int i = 0; i < 4; i++)
    if (index == i)
        ret *= (*add) * (*add);
    else
        ret *= myarray[i]*myarray[i];

要么:

double ret = (*add) * (*add);
for(int i = 0; i < 4; i++)
    ret *= myarray[i]*myarray[i];

ret /= myarray[index] * myarray[index];

由於您使用的是浮點數,所以這並不是100%等效的。

編輯:好的,看到您編輯了原始問題。 一種可以接受的替代方法是:

myarray[ indexAdd ] -= *add;

完成其余的計算后。 再次不能保證myarray[indexAdd]精確返回其舊值。

甚至更好,將舊值保存在函數頂部,然后將其還原:

float old = myarray[ indexAdd ];
myarray[ indexAdd ] += *add;
//do work
myarray[ indexAdd ] = old;
double afunction(double *myarray, int index, double *add)
{   
    double ret = (*add) * (*add);
    for(int i = 0; i < 4; i++)
        if( i != index )
            ret *= myarray[i]*myarray[i];
    return ret;
}

有幾種可能的解決方案:

顯而易見的是:

double
aFunction( double* array, int index, double add )
{
    double result = 1.0;
    for ( int i = 0; i != 4; ++ i ) {
        double tmp = array[i];
        if ( i == index ) {
            tmp += add;
        }
        result *= tmp * tmp;
    }
    return result;
}

可能更快(如果不在循環中),但結果可能不同:

double
aFunction( double* array, int index, double add )
{
    double result = 1.0;
    for ( int = 0; i != 4; ++ i ) {
        result *= array[i] * array[i];
    }
    //  Since we multiplied by array[i]^2, when we should
    //  have multipied by (array[i] + add)^2...
    result *= 2 * array[index] * add + add * add;
    return result;
}

我對此是否值得為四個元素組成的數組感到疑惑: if可能不比最終的額外計算昂貴, if這四個元素是否值得。 但是,對於更長的陣列,可能值得考慮。

最后,更多參考資料,因為它確實很丑陋,並且只能在單線程環境中工作:

double
aFunction( double* array, int index, double add )
{
    array[index] += add;
    double result = 1.0;
    for ( int i = 0; i != 4; ++ i ) {
        result *= array[i] * array[i];
    }
    array[index] -= add;
    return result;
}

根據實際的硬件和編譯器優化,這可能是最快的。 (但是同樣,對於四個要素,這還不確定。)

關於該代碼的另外兩個注釋:如果您不打算修改array ,則可能應將其作為double const*傳遞(這消除了上面的最后一種可能性),並且由於您所做的只是讀取單個值,因此實際上沒有指向傳遞add作為指針; 在上面的代碼中,我已經按值傳遞了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM