LINUX.ORG.RU

Объясните сишную магию

 ,


11

14

Пытался понять как реализовать SVG фильтр feComposite, ибо SVG дока унылая, поэтому залез в сорцы вебкита. Там тоже документации ноль, ещё и код очень странный.

Вот что это за ужас (src):

static unsigned char clampByte(int c)
{
    unsigned char buff[] = { static_cast<unsigned char>(c), 255, 0 };
    unsigned uc = static_cast<unsigned>(c);
    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
}

Я так понимаю, они проверяют что int в 0..255 диапазоне, но уж слишком странным образом.

UPD: коммит, который добавил этот код.

★★★★★

Последнее исправление: RazrFalcon (всего исправлений: 1)

Ответ на: комментарий от lovesan

Пока туда-сюда с видеокарты данные гоняются можно уснуть

сейчас рулит тренд в сторону SoC с аппаратным ускорением нужных функций и zero copy - оптимизации кода CPU практически не имеет значения потому что CPU в основном раздаёт задания блокам аппаратного ускорения а они имет прямой доступ к общей внешней памяти.

anonymous
()
Ответ на: комментарий от lovesan

Пока туда-сюда с видеокарты данные гоняются

  • Не делай так, залей один раз и дальше работай на видеокарте
  • Профит
anonymous
()
Ответ на: комментарий от EXL

Я постоянно задаю вопросы на SVG WG. Дельных ответов мало, ибо я уже в такие дебри залез, что и сами авторы не знают ответа.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от hgt54r

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feComposite

Это копипаста из официальной спеки, которая ничего не объясняет. Мало того, что k1-4 должны быть в 0..1 диапазоне, что не указано. Так ещё и холст должен использовать конкретный алгоритм premultiplied alpha. Что тоже не указано. И каналы пикселя должны переводится в 0..1 диапазон из 0..255. Этого тоже нет. Вот вам и спека. Толку 0.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Меняешь в сабжевом коде битозадротство на сравнение и всё. С GCC 7.3 и ассемблерный дамп идентичный, и работает одинаково в пределах погрешности.

Если я чего-то не понял, ты поясни, а не выпендривайся.

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Заложиться на неочевидную оптимизацию, на компилятор и версию? Сомнительная альтернатива.

Я просто думаю что врываться вот так с шашкой - тоже выпендреж. Код не школьник писал чтоб во дворе показать.

anonymous
()

здарова мужики

результирую тред:

1) тс растодрочер 2) оригинальный код говно ибо не имеет комментариев и вообще типизация убита 3) автор оригинального кода, возможно, хотел сделать процедуру, которая выполняется за определённое (неизменное?) время 4) НОРМАЛЬНЫЕ бенчи никто не делал и как работает CPU никто так и не знает, а те кто делают видимость что знают хуже первых 5) Бытиё - тлен, царь - лох

anonymous
()
Ответ на: комментарий от i-rinat

кстати мне вот непонятны люди которые юзают int для чего-то дискретного а не для подсчёта количества картошки в ведре

ибо намного лучше юзать фиксированные типы из stdint.h

в чём их проблема?

anonymous
()
Ответ на: комментарий от RazrFalcon

Империя сишников нанесла ответный удар? Ты чего их дразнишь?))

dave ★★★★★
()
Ответ на: комментарий от anonymous

ибо намного лучше юзать фиксированные типы из stdint.h

Чем лучше?

в чём их проблема?

Это у тебя какие-то проблемы, похоже.

anonymous
()
Ответ на: комментарий от Harald

А нужны? Если бы меня анонимус не попячил, я бы не усомнился и не пошел проверять.

1c1
< static unsigned char clampByte(int c)
---
> static unsigned char clampByte_w_cmp(int c)
5c5
<     return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
---
>     return buff[(c < 0) + (uc > 255)];
$ gcc -O2 t.cpp

$ ./a.out 
initialized source buffer
clampByteSimple(): 262287 clocks clampsum 18446744073676000951
clampByte(): 88535 clocks clampsum 18446744073676000951
clampByte_w_cmp(): 90905 clocks clampsum 18446744073676000951
clampByte_tsar(): 68126 clocks clampsum 18446744073676000951
clampByte_ffmpeg(): 65815 clocks clampsum 18446744073676000951

$ clang -O2 t.cpp

$ ./a.out 
initialized source buffer
clampByteSimple(): 273785 clocks clampsum 18446744073675998095
clampByte(): 71561 clocks clampsum 18446744073675998095
clampByte_w_cmp(): 74925 clocks clampsum 18446744073675998095
clampByte_tsar(): 53701 clocks clampsum 18446744073675998095
clampByte_ffmpeg(): 60412 clocks clampsum 18446744073675998095

$ ./a.out 
initialized source buffer
clampByteSimple(): 275660 clocks clampsum 18446744073675998727
clampByte(): 74153 clocks clampsum 18446744073675998727
clampByte_w_cmp(): 73459 clocks clampsum 18446744073675998727
clampByte_tsar(): 54944 clocks clampsum 18446744073675998727
clampByte_ffmpeg(): 59988 clocks clampsum 18446744073675998727

$ ./a.out 
initialized source buffer
clampByteSimple(): 278072 clocks clampsum 18446744073675998451
clampByte(): 73116 clocks clampsum 18446744073675998451
clampByte_w_cmp(): 76347 clocks clampsum 18446744073675998451
clampByte_tsar(): 55825 clocks clampsum 18446744073675998451
clampByte_ffmpeg(): 62721 clocks clampsum 18446744073675998451

$ gcc -march=native -O3 t.cpp

$ ./a.out 
initialized source buffer
clampByteSimple(): 258629 clocks clampsum 18446744073675991534
clampByte(): 86137 clocks clampsum 18446744073675991534
clampByte_w_cmp(): 83230 clocks clampsum 18446744073675991534
clampByte_tsar(): 48797 clocks clampsum 18446744073675991534
clampByte_ffmpeg(): 44975 clocks clampsum 18446744073675991534

Или ты про дамп?

WitcherGeralt ★★
()
Ответ на: комментарий от anonymous

Код не школьник писал чтоб во дворе показать

Мотивация у автора, мягко говоря, сомнительная, так что не факт.

WitcherGeralt ★★
()
Ответ на: комментарий от anonymous2

LOL код посмотри, какие нах указатели?!

https://timsong-cpp.github.io/cppwp/n4659/expr.sub

The expression E1[E2] is identical (by definition) to *((E1)+(E2))

anonymous
()
Ответ на: комментарий от i-rinat

Проблема не в касте. Проблема в том, что после каста работает, предполагая что числа в дополнительном коде (twos-complement).
Twos-complement стандартизован? А если стандартизован, то что происходит на железе, где другой формат представления чисел, принудительная конвертация в дополнительный код?

anonymous
()
Ответ на: комментарий от anonymous

А если стандартизован, то что происходит на железе, где другой формат представления чисел

На таком вебкит не запускают.

anonymous
()
Ответ на: комментарий от lovesan

Анекдот

#include <iostream>
#include <cstdlib>
#include <ctime>

#define NUMB 10

uint64_t rdtsc( void ) {
   union sc {
      struct { uint32_t lo, hi; } r;
      uint64_t f;
   } sc;
   __asm__ __volatile__ ( "rdtsc" : "=a"( sc.r.lo ), "=d"( sc.r.hi ) );
   return sc.f;
}

unsigned calibr( int rep ) {
   uint64_t n, m, sum = 0;
   n = m = ( rep >= 0 ? NUMB : rep );
   while( n-- ) {
      uint64_t cf, cs;
      cf = rdtsc();
      cs = rdtsc();
      sum += cs - cf;
   }
   return (uint32_t)( sum / m );
}

unsigned char clampByteSimple(int c)
{
    if(c < 0) return 0;
    else if(c > 255) return 255;
    else return (unsigned char)c;
}

static unsigned char clampByte(int c)
{
    unsigned char buff[] = { static_cast<unsigned char>(c), 255, 0 };
    unsigned uc = static_cast<unsigned>(c);
    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
}

int main()
{
    int array[30000];
    
    srand(time(NULL));
    for(int i = 0; i < 29999; i++)
        array[i] = rand();
    
    long cali = calibr(1000);
    
    unsigned long long t1 = rdtsc();
    for(int i = 0; i < 29999; i++)
        clampByte(array[i]);
    t1 = rdtsc() - t1 - cali;
    
    unsigned long long t2 = rdtsc();
    for(int i = 0; i < 29999; i++)
        clampByteSimple(array[i]);
    t2 = rdtsc() - t2 - cali;
    
    std::cout << "clampByte: " << t1 << std::endl;
    std::cout << "clampByteSimple: " << t2 << std::endl;
}

clampByte: 1811387
clampByteSimple: 1004949

Deleted
()
Ответ на: комментарий от anonymous

Это число случайное событие, как и то, что UB чисто случайно иногда не форматирует жесткий диск.

anonymous
()
Ответ на: комментарий от Harald

Snapdragon 660, clang 7.0 с -O2.

clampByteSimple(): 151404 clocks clampsum 8556919585
clampByte(): 182863 clocks clampsum 8556919585
clampByte_w_cmp(): 182881 clocks clampsum 8556919585
clampByte_tsar(): 123931 clocks clampsum 8556919585
clampByte_ffmpeg(): 137523 clocks clampsum 8556919585
WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это число случайное событие

Нет. Но код действительно не портабельный.

anonymous
()
Ответ на: комментарий от anonymous

Почему ты такой любопытный? Интересно сколько времени можно общаться вопросами))

Twissel ★★★★★
()
Ответ на: комментарий от WitcherGeralt

А можешь если не сложно ещё один вариант тестонуть, или ткнуть на исходники теста:

#include <functional>
template <class _Ty, class _Pr>
constexpr const _Ty& clampImpl(const _Ty& _Val, const _Ty& _Min_val, const _Ty& _Max_val,
    _Pr _Pred) {   
    // returns _Val constrained to [_Min_val, _Max_val] ordered by _Pred
    return _Pred(_Max_val, _Val) ? _Max_val : _Pred(_Val, _Min_val) ? _Min_val : _Val;
}

template <class _Ty>
constexpr const _Ty& clamp(
    const _Ty& _Val, const _Ty& _Min_val, const _Ty& _Max_val) { 
    // returns _Val constrained to [_Min_val, _Max_val]
    return clampImpl(_Val, _Min_val, _Max_val, std::less<>());
}


constexpr unsigned char clampByteMS(int c)
{
    return clamp(c, 0, 255);
}

Спасибо!

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Объясните сишную магию (комментарий)

$ gcc -O2 t.cpp
...
clampByte_tsar(): 72591 clocks clampsum 18446744073675991483
clampByte_ffmpeg(): 68560 clocks clampsum 18446744073675991483
clampByteMS(): 70046 clocks clampsum 18446744073675991483
...
clampByte_tsar(): 71298 clocks clampsum 18446744073676001052
clampByte_ffmpeg(): 71267 clocks clampsum 18446744073676001052
clampByteMS(): 69501 clocks clampsum 18446744073676001052
...
clampByte_tsar(): 73813 clocks clampsum 18446744073675987679
clampByte_ffmpeg(): 71018 clocks clampsum 18446744073675987679
clampByteMS(): 75695 clocks clampsum 18446744073675987679

$ gcc -march=native -O3 t.cpp
...
clampByte_tsar(): 52011 clocks clampsum 18446744073675995756
clampByte_ffmpeg(): 38675 clocks clampsum 18446744073675995756
clampByteMS(): 40935 clocks clampsum 18446744073675995756
...
clampByte_tsar(): 49213 clocks clampsum 18446744073675996440
clampByte_ffmpeg(): 39482 clocks clampsum 18446744073675996440
clampByteMS(): 39022 clocks clampsum 18446744073675996440
...
clampByte_tsar(): 47742 clocks clampsum 18446744073676001154
clampByte_ffmpeg(): 50538 clocks clampsum 18446744073676001154
clampByteMS(): 39548 clocks clampsum 18446744073676001154

$ clang -O2 t.cpp
...
clampByte_tsar(): 65471 clocks clampsum 18446744073675994365
clampByte_ffmpeg(): 74179 clocks clampsum 18446744073675994365
clampByteMS(): 306803 clocks clampsum 18446744073675994365
WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Короче, шлангу поплохело.

Да, спасибо за тест.

Это я посмотрел в MS реализацию clamp, просто тут приводили результаты std::clamp, но это был gcc std::clamp, захотелось посмотреть результаты std::clamp от MS.

fsb4000 ★★★★★
()
Ответ на: комментарий от anonymous

Нет, все операции над unsigned вполне определены, насколько я помню

SeTSeR
()
Ответ на: Анекдот от Deleted

В чём анекдот? В том, что компилятор оптимизирует эти циклы в ноль? Я не понимаю, что ты измеряешь.

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

Проблема не в касте. Проблема в том, что после каста работает, предполагая что числа в дополнительном коде (twos-complement).

Результат каста определён таким образом, что в two’s complement достаточно просто биты int рассматривать как биты unsigned int без каких-либо преобразований. Если используется не two’s complements, компилятор будет вынужден производить некоторые действия.

В стандарте говорится (это C99, кажется):

6.3.1.3 Signed and unsigned integers

  1. When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
  2. Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 49)
  3. Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

Если значение int больше нуля, то ничего делать не надо. Если меньше нуля, добавляем 2^32. Поэтому на x86 для преобразования достаточно делать ничего — просто использовать это значение как unsigned, и всё уже по стандарту.

Twos-complement стандартизован?

Нет. Но вот такие места в стандарте удобнее для машин с two’s complement. Как будто прямо для них и писалось. Стандартизировать two’s complement вроде хотят в новой ревизии C++.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)

ловите портянку тестов с разными входными данными :)

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <time.h>
#include <stdint.h>

#define DATA_ITEMS 64*1024*1024
int data[DATA_ITEMS];


static unsigned char clampByte(int c)
{
    unsigned char buff[] = { static_cast<unsigned char>(c), 255, 0 };
    unsigned uc = static_cast<unsigned>(c);
    return buff[!!(uc & ~0xff) + !!(uc & ~(~0u >> 1))];
}

static unsigned char clampByteSimple(int c)
{
    if(c < 0) return 0;
    else if(c > 255) return 255;
    else return (unsigned char)c;
}

uint8_t clampb(int32_t c) {
  uint32_t uc = c;  
  uint32_t res = 255 * !(c < 0);
  if(uc < 255) return uc;
  return res;
}

int main(int argc, char **argv)
{
        int fd;
        unsigned long c = 0, clampsum = 0;
        clock_t s, e, simpleResult, originalResult, tsarResult;

        fd = open("/dev/urandom", O_RDONLY);

        if (fd == -1)
        {
                puts("unable to open /dev/urandom");
                return -1;
        }

        do 
        {
                c += read(fd, (char*)data + c, sizeof (data) - c);

        }while(c < sizeof data);

        puts("initialized source buffer");

//////////////////
        puts("Test #1, random data:");

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByte(data[c]);
        e = clock();

        printf("clampByte(): %lu clocks clampsum %lu\n", originalResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByteSimple(data[c]);

        e = clock();

        printf("clampByteSimple(): %lu clocks clampsum %lu\n", simpleResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampb(data[c]);

        e = clock();

        printf("clampByte_tsar(): %lu clocks clampsum %lu\n", tsarResult = (e - s), clampsum);

        printf("orig vs simple: %gx, tsar vs simple: %gx\n", (float)simpleResult/originalResult, (float)simpleResult/tsarResult);
////////////////////////////////////
        {
                int datavals[] = {-1, 127, 257, 0};

                for (c = 0; c < DATA_ITEMS; c++)
                        data[c] = datavals[data[c] % 4];
        }

        puts("Test #2, -1,127,257,0:");

        clampsum = 0;
        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByte(data[c]);
        e = clock();

        printf("clampByte(): %lu clocks clampsum %lu\n", originalResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByteSimple(data[c]);

        e = clock();

        printf("clampByteSimple(): %lu clocks clampsum %lu\n", simpleResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampb(data[c]);

        e = clock();

        printf("clampByte_tsar(): %lu clocks clampsum %lu\n", tsarResult = (e - s), clampsum);

        printf("orig vs simple: %gx, tsar vs simple: %gx\n", (float)simpleResult/originalResult, (float)simpleResult/tsarResult);
/////////////////////////////////////////
        for (c = 0; c < DATA_ITEMS; c++)
                data[c] = clampByte(c);

        puts("Test #3, preclamped data:");

        clampsum = 0;
        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByte(data[c]);
        e = clock();

        printf("clampByte(): %lu clocks clampsum %lu\n", originalResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByteSimple(data[c]);

        e = clock();

        printf("clampByteSimple(): %lu clocks clampsum %lu\n", simpleResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampb(data[c]);

        e = clock();

        printf("clampByte_tsar(): %lu clocks clampsum %lu\n", tsarResult = (e - s), clampsum);

        printf("orig vs simple: %gx, tsar vs simple: %gx\n", (float)simpleResult/originalResult, (float)simpleResult/tsarResult);

//////////////
        puts("Test #4, 257:");

        for (c = 0; c < DATA_ITEMS; c++)
                data[c] = 257;

        clampsum = 0;
        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByte(data[c]);
        e = clock();

        printf("clampByte(): %lu clocks clampsum %lu\n", originalResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByteSimple(data[c]);

        e = clock();

        printf("clampByteSimple(): %lu clocks clampsum %lu\n", simpleResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampb(data[c]);

        e = clock();

        printf("clampByte_tsar(): %lu clocks clampsum %lu\n", tsarResult = (e - s), clampsum);

        printf("orig vs simple: %gx, tsar vs simple: %gx\n", (float)simpleResult/originalResult, (float)simpleResult/tsarResult);

//////////////////
        puts("Test #4, -1:");

        for (c = 0; c < DATA_ITEMS; c++)
                data[c] = -1;

        clampsum = 0;
        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByte(data[c]);
        e = clock();

        printf("clampByte(): %lu clocks clampsum %lu\n", originalResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampByteSimple(data[c]);

        e = clock();

        printf("clampByteSimple(): %lu clocks clampsum %lu\n", simpleResult = (e - s), clampsum);

        clampsum = 0;

        s = clock();

        for (c = 0; c < DATA_ITEMS; c++)
                clampsum += clampb(data[c]);

        e = clock();

        printf("clampByte_tsar(): %lu clocks clampsum %lu\n", tsarResult = (e - s), clampsum);

        printf("orig vs simple: %gx, tsar vs simple: %gx\n", (float)simpleResult/originalResult, (float)simpleResult/tsarResult);

        return 0;
}
Harald ★★★★★
()
Ответ на: комментарий от Harald
g++-8.2.0 -o clamptest -O2 clamp.cpp
./clamptest 
initialized source buffer
Test #1, random data:
clampByte(): 68991 clocks clampsum 8555683262
clampByteSimple(): 248676 clocks clampsum 8555683262
clampByte_tsar(): 65709 clocks clampsum 8555683262
orig vs simple: 3.60447x, tsar vs simple: 3.7845x
Test #2, -1,127,257,0:
clampByte(): 69517 clocks clampsum 3213152209
clampByteSimple(): 219396 clocks clampsum 3213152209
clampByte_tsar(): 65299 clocks clampsum 3213152209
orig vs simple: 3.156x, tsar vs simple: 3.35987x
Test #3, preclamped data:
clampByte(): 69517 clocks clampsum 17112727680
clampByteSimple(): 62822 clocks clampsum 17112727680
clampByte_tsar(): 65924 clocks clampsum 17112727680
orig vs simple: 0.903693x, tsar vs simple: 0.952946x
Test #4, 257:
clampByte(): 69978 clocks clampsum 17112760320
clampByteSimple(): 62370 clocks clampsum 17112760320
clampByte_tsar(): 65213 clocks clampsum 17112760320
orig vs simple: 0.89128x, tsar vs simple: 0.956404x
Test #4, -1:
clampByte(): 68893 clocks clampsum 0
clampByteSimple(): 41736 clocks clampsum 0
clampByte_tsar(): 65508 clocks clampsum 0
orig vs simple: 0.605809x, tsar vs simple: 0.637113x

это всё на Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz

Harald ★★★★★
()
Последнее исправление: Harald (всего исправлений: 1)
Ответ на: комментарий от Harald

Raspberry Pi 3, ARMv7 Processor rev 4 (v7l)

pi@raspberrypi:~ $ arm-linux-gnueabihf-g++-6 -o clamptest -O2 clamp.cpp 
pi@raspberrypi:~ $ ./clamptest 
initialized source buffer
Test #1, random data:
clampByte(): 646436 clocks clampsum 4261882372
clampByteSimple(): 604309 clocks clampsum 4261882372
clampByte_tsar(): 377521 clocks clampsum 4261882372
orig vs simple: 0.934832x, tsar vs simple: 1.60073x
Test #2, -1,127,257,0:
clampByte(): 657961 clocks clampsum 3187766157
clampByteSimple(): 600058 clocks clampsum 3187766157
clampByte_tsar(): 379549 clocks clampsum 3187766157
orig vs simple: 0.911996x, tsar vs simple: 1.58098x
Test #3, preclamped data:
clampByte(): 708821 clocks clampsum 4227825792
clampByteSimple(): 439033 clocks clampsum 4227825792
clampByte_tsar(): 378935 clocks clampsum 4227825792
orig vs simple: 0.619385x, tsar vs simple: 1.1586x
Test #4, 257:
clampByte(): 647483 clocks clampsum 4227858432
clampByteSimple(): 439541 clocks clampsum 4227858432
clampByte_tsar(): 380720 clocks clampsum 4227858432
orig vs simple: 0.678846x, tsar vs simple: 1.1545x
Test #4, -1:
clampByte(): 647703 clocks clampsum 0
clampByteSimple(): 377338 clocks clampsum 0
clampByte_tsar(): 388563 clocks clampsum 0
orig vs simple: 0.582579x, tsar vs simple: 0.971111x
Harald ★★★★★
()
Ответ на: комментарий от Deleted

Вставь printf’ы до и после цикла, посмотри на сгенерированный код. Там ничего от циклов не осталось.

Посмотри, как @Harald делает. Видишь, он суммирует возвращаемые значения и выводит результат на печать? Это не даёт компилятору выбросить замеряемую часть кода.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.