簡體   English   中英

在多線程程序中使用exprtk

[英]Using exprtk in a multithreaded program

我需要編寫一個程序,其中頻繁地評估字符串表達式。 表達式的示例如下:

"x0*a0*a0+x1*a1+x2*a2+x3*a3+x4*a4....."

表達式可以很長,字符串可以包含多個這樣的表達式。

我使用C ++庫exprtk編寫了一些測試代碼。

vector<std::string> observation_functions;
vector<std::string> string_indices;


template<typename T>
float* get_observation(float* sing_j, float* zrlist, int num_functions,int num_variables)
{
    //omp_set_nested(1);

    float* results = (float*)malloc(sizeof(float)*num_functions);
    exprtk::symbol_table<float> symbol_table;

    exprtk::expression<T> expression;
    exprtk::parser<T> parser;
    int i;
    for( i = 0; i < num_variables; i++)
    {
            symbol_table.add_variable("x"+string_indices[i], sing_j[i]);
            symbol_table.add_variable("a"+string_indices[i], zrlist[i]);
    }

    expression.register_symbol_table(symbol_table);
    for(i = 0; i < num_functions; i++)
    {
            parser.compile(observation_functions[i],expression);
            results[i] = expression.value();
    }
    return results;
}



int main()
{

    for( int i = 0; i < 52; i++)
    {

    ostringstream s2;
    s2<<i;
    string_indices.push_back(s2.str());
    }



    string hfun ="x0*a0*a0+x1*a1+x2*a2+x3*a3+x4*a4+x5*a5+x6*a6+x7*a7+x8*a8+x9*a9+x10*a10+x11*a11+x12*a12+x13*a13+x14*a14+x15*a15+x16*a16+x17*a17+x18*a18+x19*a19+x20*a20+x21*a21+x22*a22+x23*a23+x24*a24+x25*a25+x26*a26+x27*a27+x28*a28+x29*a29+x30*a30+x31*a31+x32*a32+x33*a33+x34*a34+x35*a35+x36*a36+x37*a37+x38*a38+x39*a39+x40*a40+x41*a41+x42*a42+x43*a43+x44*a44+x45*a45+x46*a46+x47*a47+x48*a48+x49*a49+x50*a50+x51*a51 ";


    boost::split(observation_functions, hfun, boost::is_any_of(" "));
    float *a=(float*)malloc(52*sizeof(float));
    float* c=(float*)malloc(52*sizeof(float));

    struct timeval t0,t1;
    gettimeofday(&t0, 0);
    for(int j=0; j < 210; j++)
        #pragma omp parallel for schedule(static,1) num_threads(8)
        for(int i=0;i<104;i++)
            float* b =get_observation<float>(a,c,1,52);
    gettimeofday(&t1, 0);
    long elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
    cout<<"elapsed:"<<elapsed<<endl;

}   

請注意,這是測試代碼。 實際上,每個線程將使用不同的值集來評估表達式。 這段代碼工作正常,但我需要讓它更快。

基於其他一些實驗,我發現我不能與多個線程共享一個符號表來更快地計算單個表達式。 在多個線程之間共享符號表會導致內存損壞錯誤。

有人可以提供一些關於如何提高性能的建議。

假設你有N線程。 比,創建Nexprtk -相關對象(包括symbol_tableexpressionparser主程序 )(功能 ,外for循環)。

您可以使用vector<>來存儲它們:例如,對於expression對象,它將是vector<expression> expressions;

然后,在調用函數時傳遞對這些對象的引用,

for(int i=0;i<104;i++)
    get_observation<float>(expressions[i], more params here..)

模板函數定義: template <typename T> T* get_observation(expression & exp, more params here..)

你可以創建一組對象,並通過復制制作其他對象,正如Aloalo 建議的那樣

PS首選使用智能指針, https://stackoverflow.com/a/19042634不要忘記刪除本地某處分配的內存。

您可以嘗試僅構建一次exprtk對象,並為每個線程制作它們的副本。 如果復制exprtk對象比構造它們更快,這應該更快。

暫無
暫無

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

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