crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> тестирование toolchain
igor_bogomolov
  опции профиля:
сообщение 17.9.2011, 21:45
Сообщение #1


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Кто нибудь знает какие-нибудь разумные фреймворки для тестирования тулчейнов?

Задача у меня следующая. Я собираю различные тулчейны для одной и той же arm архитектуры (отличаются версиями gcc и опциями конфигурирования пакетов).
Мне нужно знать какой из них лучше с точки зрения производительности. Интересует скорость работы с памятью, скорость работы математических библиотек, в особенности с точкой (т.к. процессор без fpu), скорость работы с текстом, с потоками и т.д.

У кого есть опыт в этом деле?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 20.9.2011, 23:37
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Нашел несколько небольших примеров: libc-bench, strbench (это из того что хоть как то понравилось). Хочу собрать их в одно целое, привести вывод к общему виду, добавить недостающие части. Одна из недостающих частей - это тесты libm. Нацарапал быстренько такой тест, хочется услышать от других на сколько он адекватный?

Раскрывающийся текст
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>

#define PI 3.14159265

void print_stats(const char *name, struct timespec tv0)
{
    FILE *f;
    char buf[256];
    struct timespec tv;
    int maj, min, in_heap=0;
    unsigned long l;
    size_t vm_size=0, vm_rss=0, vm_priv_dirty=0;

    clock_gettime(CLOCK_REALTIME, &tv);
    tv.tv_sec -= tv0.tv_sec;
    if ((tv.tv_nsec -= tv0.tv_nsec) < 0) {
        tv.tv_nsec += 1000000000;
        tv.tv_sec--;
    }

    f = fopen("/proc/self/smaps", "rb");
    if (f) while (fgets(buf, sizeof buf, f)) {
        if (sscanf(buf, "%*lx-%*lx %*s %*lx %x:%x %*lu %*s", &maj, &min)==2)
            in_heap = (!maj && !min && !strstr(buf, "---p") && (strstr(buf, "[heap]") || !strchr(buf, '[')));
        if (in_heap) {
            if (sscanf(buf, "Size: %lu", &l)==1) vm_size += l;
            else if (sscanf(buf, "Rss: %lu", &l)==1) vm_rss += l;
            else if (sscanf(buf, "Private_Dirty: %lu", &l)==1) vm_priv_dirty += l;
        }
    }
    if (f) fclose(f);
    printf(": %-15s : %ld.%.9ld   : %-6zu   : %-6zu   : %-6zu   :\n",
        name, (long)tv.tv_sec, (long)tv.tv_nsec,
        vm_size, vm_rss, vm_priv_dirty);
}

void run_bench(const char *name, double (*bench)(double), double param)
{
    int k;
    volatile double result;
    struct timespec tv0;
    pid_t p = fork();                                                                                                                                                                                                
    if (p) {
        int status;
        wait(&status);
        return;
    }

    clock_gettime(CLOCK_REALTIME, &tv0);
    for (k = 0; k < 1000000; ++k) {
        result = bench(param);
        assert(!result || result);
    }
    print_stats(name, tv0);
    exit(0);
}

void run_benchf(const char *name, float (*benchf)(float), float param)
{
    int k;
    volatile float result;
    struct timespec tv0;
    pid_t p = fork();
    if (p) {                                                                                                                                                                                                    
        int status;
        wait(&status);
        return;
    }

    clock_gettime(CLOCK_REALTIME, &tv0);
    for (k = 0; k < 1000000; ++k) {
        result = benchf(param);
        assert(!result || result);
    }
    print_stats(name ,tv0);
    exit(0);
}

int main (int argc, char *argv[])
{
    printf ("--------------------------------------------------------------------\n");
    printf (":                   Trigonometric functions                        :\n");
    printf ("--------------------------------------------------------------------\n");
    printf (": Name            : Time          : Virt     : Res      : Dirty    :\n");
    printf ("--------------------------------------------------------------------\n");

    run_bench ("sin",  sin,  30.0*PI/180);
    run_benchf("sinf", sinf, 30.0*PI/180);
    run_bench ("cos",  cos,  60.0*PI/180);
    run_benchf("cosf", cosf, 60.0*PI/180);
    run_bench ("tan",  tan,  45.0*PI/180);
    run_benchf("tanf", tanf, 45.0*PI/180);

    run_bench ("asin",  asin,  0.5);
    run_benchf("asinf", asinf, 0.5);
    run_bench ("acos",  acos,  0.5);
    run_benchf("acosf", acosf, 0.5);
    run_bench ("atan",  atan,  1.0);
    run_benchf("atanf", atanf, 1.0);

    printf ("--------------------------------------------------------------------\n");
    printf (":                   Hyperbolic functions                           :\n");
    printf ("--------------------------------------------------------------------\n");

    run_bench ("sinh",  sinh,  0.69314718056);
    run_benchf("sinhf", sinhf, 0.69314718056);
    run_bench ("cosh",  cosh,  0.69314718056);
    run_benchf("coshf", coshf, 0.69314718056);
    run_bench ("tanh",  tanh,  0.69314718056);
    run_benchf("tanhf", tanhf, 0.69314718056);

    run_bench ("asinh",  asinh,  0.75);
    run_benchf("asinhf", asinhf, 0.75);
    run_bench ("acosh",  acosh,  1.25);
    run_benchf("acoshf", acoshf, 1.25);
    run_bench ("atanh",  atanh,  0.60);
    run_benchf("atanhf", atanhf, 0.60);

    printf ("--------------------------------------------------------------------\n");
    printf (":                   Exponential and logarithmic functions          :\n");
    printf ("--------------------------------------------------------------------\n");

    run_bench ("exp",    exp,    5.0);
    run_benchf("expf",   expf,   5.0);
    run_bench ("exp1m",  expm1,  5.0);
    run_benchf("exp1mf", expm1f, 5.0);

    run_bench ("log",    log,    5.5);
    run_benchf("logf",   logf,   5.5);
    run_bench ("log10",  log10,  1000.0);
    run_benchf("log10f", log10f, 1000.0);
    run_bench ("log1p",  log1p,  0.05);
    run_benchf("log1pf", log1pf, 0.05);

    printf ("--------------------------------------------------------------------\n");
    printf (":                   Power functions                                :\n");
    printf ("--------------------------------------------------------------------\n");

    run_bench ("sqrt",  sqrt,   1024.0);
    run_benchf("sqrtf", sqrtf,  1024.0);
    run_bench ("cbrt",  cbrt,  32768.0);
    run_benchf("cbrtf", cbrtf, 32768.0);

    printf ("--------------------------------------------------------------------\n\n");

    return 0;
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.9.2011, 20:39
Сообщение #3


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


у тебя функция print_stats немногопоточная. будет бардак при выводе на экран.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 22.9.2011, 20:43
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Iron Bug @ 22.9.2011, 21:39) *
у тебя функция print_stats немногопоточная. будет бардак при выводе на экран.

Почему? Там все линейно. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 22.9.2011, 21:23
Сообщение #5


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Iron Bug @ 22.9.2011, 21:39) *
у тебя функция print_stats немногопоточная. будет бардак при выводе на экран.
В этом варианте родительский процесс дожидается завершения порожденного процесса, только после этого продолжает свое выполнение.
Но на самом деле вы правы. Я от этого варианта уже отказался, убрал fork и вывод информации из /proc/self/smaps.
В приведенном выше варианте есть немного другой неприятный эффект. Если запускать приложение из консоли просто так, мы видим нормальный вывод. А вот если перенаправить поток в файл, начинается полная ерунда. Все что я вывел в поток ввода/вывода из родительского процесса, дублируется в дочернем.

P.S. Трудно на самом деле объяснить суть, попробуйте просто скомпилировать этот пример и поэкспериментировать немного.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.9.2011, 23:14
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(BRE @ 22.9.2011, 23:43) *
Почему? Там все линейно. :)

fork копирует ПРОЦЕСС. а процесс тут один и он не завершается при выходе из процедуры. он завершается при завершении main. и поэтому будет много-много раз выведено всё из main и вообще полный бардак.

по идее, чтобы это работало так, как задумано, нужно порождать отдельные процессы для run_bench и run_benchf.

Сообщение отредактировал Iron Bug - 22.9.2011, 23:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 22.9.2011, 23:19
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Iron Bug @ 23.9.2011, 0:14) *
fork копирует ПРОЦЕСС. а процесс тут один и он не завершается при выходе из процедуры. он завершается при завершении main. и поэтому будет много-много раз выведено всё из main и вообще полный бардак.

Ты заблуждаешься. Почитай про fork. ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 22.9.2011, 23:29
Сообщение #8


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


BRE, в чем именно заблуждение? Все происходит именно так, как написала Iron Bug.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.9.2011, 23:35
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(BRE @ 23.9.2011, 2:19) *
Ты заблуждаешься. Почитай про fork.

fork() creates a child process that differs from the parent process only in its PID and PPID.
классика жанра, однако. я это ещё на первом курсе универа читала :)
процесс в данном случае - один. ВСЯ его память, включая сегменты кода и данных и стек, копируется. с чего ради я ошибаюсь? именно так и будет: выходов из main будет столько, сколько вызовов fork плюс один.

например, потестируем:
Раскрывающийся текст

#include <sys/wait.h>
#include <iostream>

using namespace std;

void dummy()
{
    pid_t p = fork();
    if (p) {
        int status;
        wait(&status);
        return;
    }
}

int main()
{
    for(int i=0;i<3;i++)
    {
        dummy();
    }
    cout << "exit!" << endl;
    return 0;
}



:D
а теперь догадайтесь, думая логически, сколько надписей "exit!" будет на экране?
копируется ВСЁ. включая циклы.

Сообщение отредактировал Iron Bug - 22.9.2011, 23:36
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 22.9.2011, 23:38
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(igor_bogomolov @ 23.9.2011, 0:29) *
BRE, в чем именно заблуждение? Все происходит именно так, как написала Iron Bug.

Давайте смотреть код. :)
void run_bench(const char *name, double (*bench)(double), double param)
{
    ...
    pid_t p = fork();                                                                                                                                                                                                
    if (p) {
        int status;            // После форка сюда попадает parent-процесс
        wait(&status);        // Он ждет завершение child-процесса. После wait дочернего потока уже не существует!!!
        return;            // Пока child не завершиться parent процесс стоит, т.е. следующий тест запуститься только после завершения предыдущего!!!
    }

    // Сюда, после форка, попадет child-процесс.
    // Здесь он работает
    // ...
    // И завершается
    exit(0);
}


В каждый момент времени существует либо parent-процесс, либо parent-процесс и ОДИН child-процесс!

Сообщение отредактировал BRE - 22.9.2011, 23:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 24.4.2024, 13:52