Benchmark分析1:Cortexsuite-lda

1.LDA基本简介
LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,也称为一个三层贝叶斯概率模型,包含词、主题和文档三层结构。

2.热点区域分析
2.1热点函数功能分析
在这里插入图片描述

/* 1.digamma  */
double digamma(double x)
{
    double p;
    x=x+6;
    p=1/(x*x);
    p=(((0.004166666666667*p-0.003968253986254)*p+
	0.008333333333333)*p-0.083333333333333)*p;
    p=p+log(x)-0.5/x-1/(x-1)-1/(x-2)-1/(x-3)-1/(x-4)-1/(x-5)-1/(x-6);
    return p;
}

功能分析:
此函数对输入x进行了算术运算得到输出p。
此函数无for循环,但执行比例较高,说明调用次数较高,被调用所在的for循环加速价值高。

/* 2.lda_inference  */
double lda_inference(document* doc, lda_model* model, double* var_gamma, double** phi)
{
    double converged = 1;
    double phisum = 0, likelihood = 0;
    double likelihood_old = 0, oldphi[model->num_topics];
    int k, n, var_iter;
    double digamma_gam[model->num_topics];

    // compute posterior dirichlet

    for (k = 0; k < model->num_topics; k++)
    {
        var_gamma[k] = model->alpha + (doc->total/((double) model->num_topics));
        digamma_gam[k] = digamma(var_gamma[k]);  
        for (n = 0; n < doc->length; n++)
            phi[n][k] = 1.0/model->num_topics;
    }
    var_iter = 0;

    while ((converged > VAR_CONVERGED) &&
           ((var_iter < VAR_MAX_ITER) || (VAR_MAX_ITER == -1)))
    {
		var_iter++;
		for (n = 0; n < doc->length; n++)
		{
            phisum = 0;
            for (k = 0; k < model->num_topics; k++)
            {
                oldphi[k] = phi[n][k];
                phi[n][k] =
                    digamma_gam[k] + model->log_prob_w[k][doc->words[n]];

                if (k > 0)
                    phisum = log_sum(phisum, phi[n][k]);
                else
                    phisum = phi[n][k]; // note, phi is in log space
            }

            for (k = 0; k < model->num_topics; k++)
            {
                phi[n][k] = exp(phi[n][k] - phisum);
                
                var_gamma[k] =
                    var_gamma[k] + doc->counts[n]*(phi[n][k] - oldphi[k]);
                // !!! a lot of extra digamma's here because of how we're computing it
                // !!! but its more automatically updated too.
                digamma_gam[k] = digamma(var_gamma[k]);
            }
        }

        likelihood = compute_likelihood(doc, model, phi, var_gamma);
        
        assert(!isnan(likelihood));
        
        converged = (likelihood_old - likelihood) / likelihood_old;
        
        likelihood_old = likelihood;

        // printf("[LDA INF] %8.5f %1.3e\n", likelihood, converged);
    }
    return(likelihood);
}

功能分析:
此函数两个循环for-for,while-for-for;循环中调用了函数digamma和compute_likelihood。
第一个循环对输入数据进行算术运算产生了三个数组。
第二个循环消费三个数组并调用digamma函数,得到输出数据digamma_gam[]。此循环为最耗时循环。

/*  3.compute likelihood   */
double
compute_likelihood(document* doc, lda_model* model, double** phi, double* var_gamma)
{
    double likelihood = 0, digsum = 0, var_gamma_sum = 0, dig[model->num_topics];}}
    int k, n;

    for (k = 0; k < model->num_topics; k++)
    {
		dig[k] = digamma(var_gamma[k]);
		var_gamma_sum += var_gamma[k];
    }
    digsum = digamma(var_gamma_sum);

    likelihood =
		lgamma(model->alpha * model -> num_topics)
		- model -> num_topics * lgamma(model->alpha)
		- (lgamma(var_gamma_sum));

    for (k = 0; k < model->num_topics; k++)
    {
		likelihood +=
	    (model->alpha - 1)*(dig[k] - digsum) + lgamma(var_gamma[k])
	    - (var_gamma[k] - 1)*(dig[k] - digsum);

		for (n = 0; n < doc->length; n++)
		{
        	 if (phi[n][k] > 0)
        	 {
                likelihood += doc->counts[n]*
                    (phi[n][k]*((dig[k] - digsum) - log(phi[n][k])
                                + model->log_prob_w[k][doc->words[n]]));
        	 }
       }
    }
    return(likelihood);
}

功能分析:
此函数包含两个循环:for,for-for;循环中调用了digamma函数
第一个循环调用了digamma产生两个数据:一个标量,一个向量
第二个循环消费了第一循环的生产数据,循环不断进行树状计算得到输出数据likelihood。此循环为最耗时循环。

2.2热点区域调用关系分析
(1)热点函数调用
点:(self,total)
函数除去子函数的自身执行时间百分比,函数本身加上调用热点子函数总和百分比
边:(子函数执行比例,调用次数)
在这里插入图片描述

(2)lda-inference函数热点区域调用与数据流图(省略了部分非耗时循环的数据流图)
热点区域剖视借助了VTune工具,图中标红的循环为耗时最高循环
在这里插入图片描述
在这里插入图片描述
(3)compute_likelihood函数热点区域调用与数据流图(省略了部分非耗时循环的数据流图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值