×Закрыть
matlab, C++ в Self Employed
  • Интересная задачка (С/C++)

    7 лет назад и сейчас всё сильно разное. Более того разные компиляторы и разные целевые платформы и многое меняется.
    Так что подобные задачки интересны для разминки, но не более. На другом железе с другими компиляторами в другое время всё может в корне измениться.
    Эта задачка, что дает Горчак на собеседовании ни о чем, если он не расскажет в формулах, собственно что делает эта конвертация и почему тупо нельзя забить 0-ми.
    Более того форматов видео и картинок безумное море нынче и их еще плодят. Вот выше вы поразминались, но у вас картинка HWC, а многим либам предпочтительней CHW и всё, что вы выйграли здесь, проиграете в HWC->CWH.
    А еще построчные матрицы или по столбцам, а еще RGB или BGR.
    Вот объясни, с какого бодуна в OpenCV BGR дефолный, а не RGB.
    И т.д. и подобного море. А когда добавляются батчи, то там начинается безумие из всех возможных вариантов 7 буковок N, C, W, H, R, G, B. И еще стадо форматов упаковки от RGB до YUV.
    И сколько видел кода для обработки видео от 10 до 90% времени комп занимается конвертированием между форматами.

  • Интересная задачка (С/C++)

    Ты же разбираешь битовый массив, затем пихаешь разобранное в дабл, затем вынимаешь оттуда, кладешь в int8 — это для процессора громадное количество странного кода.
    По сути ты делаешь все возможное, чтобы тормознуть его.

    Поддержал: Sashka
  • Интересная задачка (С/C++)

    Если предел счетчика цикла известен GCC, то он сам все развернет по проц твой.

  • Интересная задачка (С/C++)

    Там уметь нечего. Команды SSE и AVX прилично логичнее тех, что были в FPU. И пользоваться ими проще, но начиная с GCC8 уже почти не нужно.

    Поддержал: Dmitry Derevyagin
  • Интересная задачка (С/C++)

    GCC с 8-го уже сам это неплохо умеет, если код на С ему удобен. И циклы сами разворачивают. А смотрю чего компилер наделал здесь godbolt.org. С ключиками компилятора иногда поиграться быстрее, чем ручками солнышко закатывать.
    Ну и юзаю по возможности MKL, IPP. Там у интела програмеры только подобными оптимизациями и занимаются и за очень приличные зарплаты.
    И да AVX2 и AVX512 реально круты, но из процессора интеловского делают обогреватель помещения. Пришлось поставить кулер на полкило весом и 4 тепловыми трубками, чтобы тепло отводить от проца. И двумя вентиляторами и не забывать его пылесосить вовремя.

    А в задачке выше нужно с битиками гемороиться.

    Ну и понимаю, что Горчаку нужно на разном странном железе делать и ему за это платят приличную зарплату, а мне не платят и для моих игр мне отлично хватает интеловского проца и nvidia карточки.

    В прошлый раз когда возился в AVX, GCC еще толком в него не умел.

    Ну и еще. Предел оптимизации всех этих ваших трюков — это просто пробежать чтением по всей картинке и записать ее в другое место и как я понял — он почти достижим (CPU сейчас во много раз быстрее памяти). Главное подобрать такой вариант кода для твоей версии компилятора и его ключиков, чтобы он сгенерировал правильный код для процессора твоего.

    Если не уверены в той memcpy, что у вас, то тупо прогоните картинку нужного вам размера через регистры AVX и получите предел, которого можете достигнуть.
    И не забывайте, что данные по возможности должны быть выровненные. Кстати наиболее хорошо видно, как должно быть — это ippMalloc из IPP.

    Ну и таблица, если влазит в кеш и еще влазят туда обрабатываемый данные, всегда будет быстрее. Но если таблица с обрабатываемыми не влезет хоть на 1 байт, то получите сразу приличные тормоза.
    Kегко это проверить просто умножением матриц через MKL — до некоторого размера матриц будет летать, а после некоторого его увеличения будет скачек по времени — он близок к размеру кеша L1/3.

    Поддержали: Sashka, Dmitry Derevyagin
  • Интересная задачка (С/C++)

    Не приду. Мне лень. Оно, конечно можно пострадать с AVX2. но зачем???
    Мне вот сейчас нужно оптимизнуть ресайз маски 28×28 по баунти-боксу на размер картинки со входа.
    Но про таблички напомнили мне — это хорошо.

    Поддержал: Denys Poltorak
  • Интересная задачка (С/C++)

    Так я и безработный. В офис протирать штаны категорически не хочу. А бегать и рыскать в поисках заказчиков сейчас сил нет. Играюсь вот с MaskRCNN и подобным и пытаюсь его юзать на тележке с ардуинкой (для тестов).
    Сейчас, нет ни одной модели для оного, чтобы хотя бы в 30 fps вложилась на приличном даже железе. Вот появилась новая YOLACT (какая-то интересная модификация MaskRCNN) — вот с ней и играюсь. Оригинальный код, как писал один китаец, что ее попробовал юзать, сильно питонизирован.
    А вот последовал шагам и коду того китайца и уже его код выкинул и написал постобработку сам, так быстрее работает у меня.
    Попробовал прямо на С++ из питона переносить, не получилось. Понял в деталях, написал на матлабе понятно для себя, затем сходу на С++ перенес.
    Сейчас буду вот пытаться ту модель под openvino перенести (понятно обученную уже).
    YOLACT на 1080 прекрасно в 30 fps влазит.
    Но уже там есть недоделка — часть аналогичная FasterRCNN там хуже, чем я ожидал, почему, я пока не знаю еще.

    А с работой, хрюшки стукаются, но с какой-то безумной мутью.

  • Интересная задачка (С/C++)

    Я в деталях не проверял. Мне просто было тем утром интересно вспомнить эти битовые игры со сдвигами. И в общем без особых подсказок из инета. Подобных моему варианту тут уже море положили. Но думаю, если их захочется заюзать, то подобное шаманство нужно обязательно проверять самому.
    Ну и я попытался написать так, чтобы было хоть немного понятно, что оно делает.

    З.Ы. Ну и мне уже давно не приходиться лезть в подобное, обычно оптимизация на уровне алгоритма эффективнее, такая нужна в предельных случаях, когда алгоритм на верхнем уровне вылизан. Мне же чаще нужно бывает, например, убрать лишнее копирование матриц больших или лишнее транспонирование и подобное — глубже не погружаюсь в оптимизации. А если тензоры, то как их правильнее решейпнуть, чтобы IPP заюзать (в стиле NHWC или NCWH и подобное).

  • Интересная задачка (С/C++)

    Все просто. Вот ты юзаешь эту 1/(1+e^{-x}). А какие x на входе ты просто не знаешь.
    И тут либо анализировать их, дискретизировать вход и после юзать и это долго. Или тупо и быстро функцию дернуть.
    И если ты начнешь так тонко всё оптимизировать, то собственно задачу решишь лет через 100, когда она уже никому не нужна будет.
    Вот сколько времени ты на базе опенсурсного будешь тонко оптимизировать какой кодек?
    Задачка выше — это микроскопическая часть от него.

    Но, если посмотришь на движки, что int8 умеют, то там это внутри скорее всего сделано уже.

    Но запустить метод оптимизации, по вычислению минимизирующих параметров ты в int не можешь (а что ты там оптимизируешь, нейронку или еще кучу разных алгоритмов — это не важно).
    Дальше, если тебе нужно твою модель запустить на дохлом железе, то ты просто берешь готовую реализацию на интах, если она существует. Если таковой не существует, то у заказчика просто нет денег на оплату подобных оптимизаций. Ему выгоднее пачку тесл поставить, а не платить год приличным сишникам или приплюснутым за подобное или просто списать работу в убытки (ибо за подобные оптимизации нужно платить долго и много, а взлетит продукт или нет неизвестно и тем более неизвестно. окупится-ли подобное вложение).
    Вон у Горчака такие задачки не частые, а если взять всю их контору, то не удивлюсь если подобным там занимаются 2.5 человека максимум.

    Вон минская IBA хвасталась продуктом по подсчету товаров на полках. Это задаче уже лет 7 и громадное количество пыталось ее решать на дохлом железе (в том числе и смартфоны) и всегда получалась у всех фигня. IBA тупо шлет картинку на свои сервера с теслами (или в какое облако), там ее распознает и обратно уже шлет результат. По нескольким рекламным картинкам распознается неплохо у них.
    Но могу сказать, что их решение у них покупать не будут. Сетям нужно, чтобы стояли дешевые камеры и сообщали персоналу магазина, что вот там на полке пусто и бегом товар выставлять. И стоила такая хрень не дороже 200 баксов, лучше 100.

    Вот стартап в котором я 2 года поработал. Его инвесторы свернули. дело в том, что наше решение работало, но стоило в 5-7 раз дороже, чем крупные сети готовы были заплатить. Ему нужны были хотя бы 1080 с полноценным компом, а крупные сети готовы были только на хрени за 150-200 баксов и не дороже.
    Теоретически можно было бы нанять еще сишников дорогих и за 2 года оптимизировать раза в 3, но инвестор на такое не готов был, причем с фиксами движка нейронки под себя. такое реально могут тянуть только монстры типа мордокниги, гугла, интела.
    АМД вон не тянет — они до сих пор не сделали аналога CUDA и cuDNN. Только не напоминай про ОpenCL — это что-то вечно полурабочее. Вот та же NVDIA заморочалась и сделала полный аналог IPP, называется NPP.

  • Интересная задачка (С/C++)

    Но побоялся написать.

  • Интересная задачка (С/C++)

    Если честно, то спасибо за напоминание о таком трюке. Уже и совсем забыл его.

    Поддержал: Yevgen Lasman
  • Интересная задачка (С/C++)

    Прикольное решение. Но у олдов памяти было всегда мало и на подобные таблички разменивались только там, где ее было достаточно. Ну и я как примат, таблички не любил, это уже больше чисто эмбедерские фишки. И таблички — это больше с расчетам трансцендентных функций — вот такая у меня установка.
    Ну и я надеялся на что-то сильно более красивое ;(.

  • Интересная задачка (С/C++)

    может и не самое оптимальное, но быстрее того, что производит оптимизатор компилятора раза в 2-3

    Но интересно увидеть решение Горчака.

  • Интересная задачка (С/C++)

    Ну это уже вотчина вас эмбедеров. Я в нее никогда не стремился и не полезу.
    Просто иногда бывает нужным влезть туда и на PC. Посему мне и интересны решения грамотных ембедеров, особенно в ключе, когда обрабатываются большие массивы.

    Вот с тем же yolact, там постобработка питоне и pytorch.tensor и сильно питонизировано. Во всем инете нашел только пробу одного китайца запустить ту же модель на С++. Я сначала взял его код, а он еле еле шевелится. Вот пришлось в деталях разобраться с той постобработкой и переписать на с++. Вместо 60 ms кода того китайца на 1 кадр у меня получилось 3 ms. Модель выдает около 25 ms. Как бы на сейчас меня такая скорость удовлетворяет.

    Я видел код питонистов, где 80% времени работы их проги занимали копирования массивов, что по RAM-RAM, что RAM-GPU.

  • Интересная задачка (С/C++)

    Ну, по тупому набросал и не проверил. Я сейчас выход модели yolact делаю обработку и там мне уже не до опускания в такие глубины — хватает гемора на более верхних уровнях (причем хочется писать так, чтобы я или кто другой смог прочитать написанное через полгода, посему кручусь в cv::Mat).
    И стараюсь в такие оптимизации не лезть. Почти всегда находятся оптимизации на более высоких уровнях (переделкой алгоритма), что дают результат лучше.
    Но как задачка для разминки мозгов, то, что ты кинул сюда, интересно.

  • Интересная задачка (С/C++)

    Чуть интересная тема и из 90% местных тут говно тоннами полилось. Интересно, у вас фишка такая — гадить везде, где только можно и нельзя?

  • Интересная задачка (С/C++)

    Вообще-то почти в 3 раза:

    t0: 1.39983ms t1: 0.588362ms

    Почему-то мне кажется, что подобные оптимизации сильно на конкретный процессор завязаны будут.

    В простых задачках много чертей водятся %)

    Они не простые и более того с кучей нюансов под разные процессоры. Но проблема в том, что так оптимизированный код потом никто, кроме тебя не поймет. Посему считаю, что если ну совсем жесткой необходимости нет, то нужно писать попроще и читабельнее и пусть компилятор оптимизирует сам.

    Тем ни менее жду правильное решение. Интересно же.

  • Интересная задачка (С/C++)

    inline uint8_t clamp0(int val)
    {
    	if (val < 0)
    		return 0;
    	else if (val > 255)
    		return 255;
    	else
    		return val;
    }
    
    inline uint8_t clamp1(int val)
    {
    	if (val < 0)
    		return 0;
    	else
    	{
    		int y = ~((val-256)>>24) | val;
    		return y;
    	}
    }
    
    или
    
    inline uint8_t clamp1(int val)
    {
    	int y = ((~(val-256)>>24) | val) & (~(val>>31));
    	return y;
    }
    
    вот такой вариант получается:
    t0: 1.39983ms t1: 0.588362ms
    то бишь второй вариант быстрее
    с ключами компилятора -std=gnu++17 -O3 -ftree-vectorize -funroll-loops -fno-strict-aliasing

    разницы между проверкой на < 0 или без нее нет.

    Думаю, если поиграться с AVX, AVX2 можно еще чего выйграть (но там пару дней погемороиться придется).

    З.Ы. Немного вспомнил про сдвиги с С. Наверное логические операции можно и упростить, типа минимальные диз- коньюкнивные функции повспоминать. Но без компилятора под рукой я бы не решил такую задачку. А если что-то подобное спросят на собеседовании, то сразу попрощаюсь. Код с ифами правильнее, потому как его люди читать будут. Но, как утренняя разминка задачка зашла.

    Поддержал: Viktor Musienko
  • Интересная задачка (С/C++)

    Не неправильно. Так что не знаю решения.

  • Интересная задачка (С/C++)

    Это классический древний трюк по вычислению отстатка от деления.
    На степенях двоики заменялся на сбдвиги.
    Но всегда была куча нюансов с учетом правил сдвигов (в С и асме они чуть разные).
    Важно четко осознавать и помнить правила для знаковых и беззнаковых.
    Еще в асме были циклические и не циклические сдвиги и с учетом знакового бита.
    Помню что такое там было, но как пользоваться правильно уже не помню.

← Сtrl 123456...2476 Ctrl →