其他分享
首页 > 其他分享> > BENCH_INNER:lmbench3.0 src代码宏查询

BENCH_INNER:lmbench3.0 src代码宏查询

作者:互联网

我正在阅读lmbench的创建者和源代码浏览代码的MHZ – Anatomy of a Benchmark论文.

>论文可以在@ MHz : Anatomy of a Microbenchmark下载
>源代码lmbench-3.0由Carl Staelin和Larry McVoy撰写

在BENCH_INNER()宏内部,我有一个疑问:

#define BENCH_INNER(loop_body, enough) {                \
    static iter_t   __iterations = 1;               \
    int     __enough = get_enough(enough);          \
    iter_t      __n;                        \
    double      __result = 0.;                  \
                                    \
    while(__result < 0.95 * __enough) {             \
        start(0);                       \
        for (__n = __iterations; __n > 0; __n--) {      \
            loop_body;                  \
        }                           \
        __result = stop(0,0);                   \
        if (__result < 0.99 * __enough              \
            || __result > 1.2 * __enough) {         \
            if (__result > 150.) {              \
                double  tmp = __iterations / __result;  \
                tmp *= 1.1 * __enough;          \
                __iterations = (iter_t)(tmp + 1);   \
            } else {                    \
                if (__iterations > (iter_t)1<<27) { \
                    __result = 0.;          \
                    break;              \
                }                   \
                __iterations <<= 3;         \
            }                       \
        }                           \
    } /* while */                           \
    save_n((uint64)__iterations); settime((uint64)__result);    \
}

>根据我的理解,BENCH_INNER用于自动计算所选定时间隔(‘足够’)的最佳迭代次数.循环执行直到我们继续迭代一段代码’loop_body’,这将占用我们选择的定时间隔的至少95%,其范围可以从5ms到1秒.
>为简单起见,让我们采取’足够’为10000微秒
>我们从__iterations = 1开始
>随着时间的推移,我们达到了__result>的阶段. 1.2 *’够’即__result> 12000微秒
>现在自__result> 150微秒,我们继续并缩放__iterations的值,以便__result大约等于1.1 *’够’
>但是在我们重新计算__result之前,我们会打破循环,因为早期的__result> .95 *’够’
>我们继续保存__result和修改值__iterations的值(这里__result的值不是我们保存的__iterations)

在这种情况下代码不应该重新计算__result吗?我错过了一些基本的东西吗

解决方法:

是的,这里有问题,__ result必须设置为零.

而且我可以在你的代码中看到另一个可能的问题 – 结果是在一个案例中与0.99 *足够比较而在其他情况下足够与0.95 *相比,这是一个非常可疑的错误.我建议你重写这个宏,明确说明“满足”条件并简化逻辑,首先检查良好条件.像这样:

#define SEARCH_EXIT_CASE(__result, __enough) ((__result) > 0.95 * (__enough) && (__result) < 1.2 * (__enough))

#define BENCH_INNER(loop_body, enough) {                \
    static iter_t   __iterations = 1;               \
    int     __enough = get_enough(enough);          \
    iter_t      __n;                        \
    double      __result = 0.;                  \
                                    \
    while(!SEARCH_EXIT_CASE(__result, __enough)) {             \
        start(0);                       \
        for (__n = __iterations; __n > 0; __n--) {      \
            loop_body;                  \
        }                           \
        __result = stop(0,0);                   \
        /* good result */ \
        if (SEARCH_EXIT_CASE(__result, __enough)) {         \
            break; \
        } \
        /* failure cases */ \
        if (__result > 150.) {              \
            double  tmp = __iterations / __result;  \
            tmp *= 1.1 * __enough;          \
            __iterations = (iter_t)(tmp + 1);   \
        } else { \
            if (__iterations > (iter_t)1<<27) { \
                __result = 0.;          \
                break;              \
            }                   \
            __iterations <<= 3;         \
        } \
        __result = 0.;          \
    } /* while */                           \
    save_n((uint64)__iterations); settime((uint64)__result);    \
}

另外我建议定义其他神奇的常量,如1<<<<<<<<<<<<<<<<<    ,        

标签:c-3,microbenchmark,linux,unix
来源: https://codeday.me/bug/20190825/1724422.html