LINUX.ORG.RU

Сообщения Dudraug

 

Добавить цель с распаковкой архива при его изменение

Добрый день,

Есть очень большой проект в котором огромное множество конечных таргетов, естественно все разбито по подкаталогам и местным CMake файлам. Хочется добавить таргет от которого будет зависеть часть текущих таргетов(не все) и чтобы этот таргет при сборке делал только одно - распаковывал архив(обычный tar), но только в случае если архив обновлился. То есть если архив не менялся, то просто оставляем все как есть, если менялся, то распаковываем (желательно с полным удалением результата от старой распаковки).

Пытался баловаться с add_custom_command, но ничего не вышло, добился только того, чтобы tar запускался на каждом вызове.

 , ,

Dudraug
()

Баг или фича?


#include <vector>

const size_t i = 20;


int main()
{
    //auto p = std::make_pair<void*, size_t>(nullptr, i); // doesn't work
    auto p = std::pair<void*, size_t>(nullptr, i); //works
}

gcc 9.2.0, собираю с -std=c++17

 

Dudraug
()

виртуализация и cpuflags

Добрый день, лор,

Я не сильно силен в виртуализации, поэтому есть такой вопрос.

Есть сервак с кучей виртуалок, на виртуалках через cat /proc/cpuinfo видно имя(поколение, имя проца, модель) в точности такое же как у хостовой машины. Но не видны все флаги. В частности на хостовой видны: avx512f, avx512cd, avx512vl, avx512dq, avx512bw. А на госте только avx512f, avx512cd.

Насколько мне известно виртуальная машина настроена так, чтобы она предоставляла модель процессора хоста. Раньше все было настроено несколько иначе и даже avx512f в флагах отсутствовал, а простейшие avx512f инструкции вызывали крэши(теперь нет).

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

Поискав в интернете мы нашли такой патч

https://lore.kernel.org/patchwork/patch/702644/

Который по идее должен решать эту проблему. НО 1) у нас ядро сильно(сильно-сильно) старее этого 2) обновить и пропатчить будет затруднительно с точки зрения организационной, бизнес задач и принципа «работает - не трожь».

Правильно ли я понимаю, что этот патч просто позволяет пробросить эти флаги в cpu_flags гостя и напрямую на поддерживаемый набор инструкций в виртуалке не влияет? (Возможно только на приложения которые в реалтайме проверяют cpuf_flags). Или все же влияет?

UDP: Раньше в виртуальной машине явно задавалась модель проца, да не хостовая. Флагов видно не было, любой avx512 код падал. Теперь видны avx512f и cd, а все выглядит словно работает ВСЕ тоже что и на хосте.

 , , , ,

Dudraug
()

Снизить оверхэд на первом обращение к hugepage

Добрый день. Cобственно есть огромный буфер обращение к которому вности определенный оверхэд. Решил выделить его через mmap и hugepages. Собственно все работает. Но появились неожиданно огромные потери производительности на первом обращение к этой памяти. Выделяю так:

addr = mmap(0, SIZE_DATA_RING_BUFFER , PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
if (addr !=  MAP_FAILED) {  
  m_DataRingBuffer = (uint8_t*) addr;
} else {
          ...
}

Все выглядит так, что на первом обращение система переводит hugepage из состояния reserved в выделенное состояние. До запуска программы:

HugePages_Total:       4
HugePages_Free:        3
HugePages_Rsvd:        0
После запуска, после mmap, но до первой операции чтения/записи
HugePages_Total:       4
HugePages_Free:        3
HugePages_Rsvd:        1
После первого чтения/записи
HugePages_Total:       4
HugePages_Free:        2
HugePages_Rsvd:        0

Как бороться с этим оверхэдом. Попробовал сделать так, ибо потери на инициализации для меня не существенны.

addr = mmap(0, SIZE_DATA_RING_BUFFER , PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
if (addr !=  MAP_FAILED) {  
  m_DataRingBuffer = (uint8_t*) addr;
  m_DataRingBuffer[0] = 1;
} else {
          ...
}
И это вроде помогло, но есть сомнения в корректности такого способа. Есть ли корректное решение проблемы?

 , ,

Dudraug
()

Выравнивание вложенных структур

Привожу адаптированный пример кода. Сразу скажу, что код не мой. Альтернативное решение найдено. Но понять причины проблемы все же хочется.


#include <iostream>
#include <cstring>

struct SFirstNStruct
{
    unsigned int data;
};


struct SSecondNStruct
{
    unsigned short secondField;
    unsigned short unusedField;

};

struct Data
{
    SFirstNStruct firstField;
    unsigned short secondField;
};


struct Data2
{
    SFirstNStruct firstField;
    SSecondNStruct nestedStruct;
};


int main()
{
    Data2 d2;
    char * s2 = (char*) &(d2.nestedStruct.secondField);
    char * f2 = (char*) &(d2.firstField.data);
    std::cout << s2 - f2 << std::endl;
    
    Data d;
    char * s = (char*) &d.secondField;
    char* f = (char*) &d.firstField.data;
    std::cout << s - f << std::endl;
    
    std::memcpy(&d2, &d, sizeof(Data));
    
   return 0;
}

Вся суть в последнем memcpy. Когда-то это работало, потом перестало. Стал я проводить расследование и выяснил. Data2::SSecondNStruct::secondField и Data::secondField имеют разные офсеты от начала структуры. Написал вот этот тетовый пример, который выводит 4,4. А на реальной системе 8,4. Отсюуда вопрос, что могло вызвать такое поведение? Опции компилятора, прагмы? Пока ничего не в хедерах, ни в опциях компилятора криминального не нашел. gcc 5.4 вроде.

 

Dudraug
()

Есть ли где-нибудь информация об объемах продаж моделей процессоров x86

Стало вот интересно, есть ли где-нибудь инфа о продажах сорвменных процов intel по моделям? Ну или хотя бы по видам. Например ксеонов было выпущено - столько, core i5 - столько и т.д.

Хотя на самом деле меня интересует от чего intel имеет больше дохода от десктопного железа или серверного.

 , ,

Dudraug
()

Удаленный move конструктор и передача по значению временного объекта

Добрый день,

имеется такой сферический в вакууме код

#include <iostream>


class A
{
        int i;
public:
        A() {std::cout << "A" << std::endl;}
        A(const A&) {std::cout << "const A&" << std::endl;}
//      A(A&&) {std::cout << "A&&" << std::endl;}
        A(A&&) = delete;
        ~A() {std::cout << "~A" << std::endl;}
};

void f(A a)
{
}
int main()
{
        f(A());

        return 0;
}

В g++ 6.3 (с -std=c++17) это не компилируется с ошибкой error:

use of deleted function ‘A::A(A&&)’

В g++ 7.2 (с -std=c++17) это собирается.

Вопрос: появилось ли в конечном варианте стандарта какое-нибудь требование относительно этого поведения? Если нет, то чем объяснить такое поведение компиляторов.

 ,

Dudraug
()

Какая опция линкера/компилятора отвечает за включение кода до main из либы

Всем привет.

В общем такая ситуация. Есть некая библиотека libololo.a В этом архиве содержится множество .o файлов. В том числе для avx512.

lib_ololo_avx2.o

lib_ololo_avx512.a

В исходном файле lib_ololo_avx512.cpp имеется код в глобальном пространстве (вне функций и классов).

Есть два приложения, одно компилится через самописный Makefile библиотека линкууетя -L<path> -lololo

Это приложение нормально работает.

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

Так вот, второе приложение падает до захода в main, оно и понятно - этот код должен(в глобальной области) должен выполнятся до main, а платформа имеет только avx2.

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

Я пробовал добавлять -O2 к опциям, убирать -g, а так же убрал -export-dynamic из унаследованных опций. Это все не помогло.

Есть еще какие-нибудь идеи?

P.S.: Автором обеих внешних либ является сторонний разработчик, поэтому мне надо проанализировать ситуацию и выслать свою ревью. Поэтому советы вроде «убрать код из глобальной области», «убрать avx512 из сборки для avx» не канают=)

 , ,

Dudraug
()

нет транзакции в выписке

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

 ,

Dudraug
()

безопасно ли читать в avx регистр концы массивов

Допустим есть такой случай

uint8_t arr[33] __attribute__((aligned(64)));
....

__m256i v = _mm256_load_si256((__m256i*) arr);
...
v = _mm256_load_si256((__m256i*) arr+32);

Безопасен ли такой код? Насколько я понимаю память на x86 выделяется страницами с минимальным размером в 4кб. А то в свою очердь означает, что читая 32 байта (256 бит) по выравненому указателю (по 64 байта - 512бит) мы не можем залезть в память другого приложения (или ядра) и получить неприятные последствия от этого.

Разговор тут идет только о чтение, о записи само собой в этот «хвост» и речи быть не может.

 , , ,

Dudraug
()

Как эффективно сохранить в память несколько элементов по различным адресам.

Задача примерно такая. Есть некий буфер в котором есть некоторые значения. Есть второй буфер, в котором хранятся адреса для сохранения в выходной буфер. Есть третий буфер(выходной), в который сохраняются данный из первого по адресам из второго. Перед началом сохранения вычисляется офсет во втором буфере, начиная с которого берутся адреса

То есть примерно такое

   size_t offset = calc_offset();
    
    for(size_t i = 0; i < sizeInp; ++i) {
      *(out + *(bufOffsets + offset++)) = inp[i];
    }

Можно как-нибудь оптимизировать запись в память для такого алгоритма? На данный момент это является узким местом самой тяжелой функции в системе. Остальную часть функции уже удалось оптимизировать через avx2.

Значения в bufOffsets само собой могут отличаться от соседних значений больше чем на 1 (то есть куском через тот же avx не записать). Подойдут решения как общие(с++/c), так и под асм x86(x86_64).

Заранее спасибо.

 , ,

Dudraug
()

Ищу приложение фонарик, но непростое

Всем привет! В общем проблема такая. Есть одно приложение которое использует камеру, но при этом не включает подсветку вспышкой и настройки такой нет. Так вот хочется подсветить это через другое приложение. Но встроенный фонарик при сворачивание отключается.

Нет ли такого приложение фонарик, которое работало бы в фоне?

 adnroid,

Dudraug
()

Как заставить подобный код НЕ компилироваться?

Всем привет, сделал такой код, ожидал, что выдаст ошибку компилции, но все собралось

#include <iostream>


class Test
{
public:
//  static void test()
//  {
//   some action
// }
};


template<class T>
class ITest
{
public:
  void test()
  {
    T::test();
  }

};

typedef ITest<Test> TTest;

int main()
{
  TTest test;
  return 0;
}

Как можно получить ошибку компиляции в таком коде. Сразу поясню зачем это нужно. Ведется разработка под микроконтроллеры и всякие наследования, вирт. функции там нежелательны, а сделать реализацию заменяемой для разных железок (при одинаковом использование в коде) хочется. Сейчас это сделано так

  typdef ImplClass alias;

  ...
  alias::Do();

где методы ImplClass - статические функции.

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

Поэтому у меня два вопроса: почему это компилится? как можно сделать то чего я хочу иначе?

 ,

Dudraug
()

синглтон падает при вызоде из main

Всем привет, имеется такой синглтон

class CSocketController {
	std::vector<int> SocketsLst;
	CSocketController() = default;


	std::mutex mtx;
public:

	CSocketController(const CSocketController&) = delete;
	CSocketController(CSocketController&&) = delete;
	CSocketController& operator=(const CSocketController&) = delete;
	CSocketController& operator=(CSocketController&&) = delete;

	static CSocketController& instance()
	{
		static CSocketController inst;
		return inst;
	}

	void AddSocket(int fd)
	{
		std::unique_lock<std::mutex>(mtx);
		SocketsLst.push_back(fd);
	}


	virtual ~CSocketController() = default;
};

И есть приложение которое запускает практически одновременно ок 100 тредов, каждый из которых юзает функцию AddSocket.

В итоге приложение при выходе крашется в самом конце, main полностью отработал. По дампу вычислил, что краш происходит на

virtual ~CSocketController() = default;

Крайне редко краш случается и при вызове функции AddSocket в одном и тредов, точнее на локе мьютекса, но это редко.

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

Судя по дампу проблема в алокаторах в vector

Это я что-то делаю не так? Или это баг стандартной либы?

 , ,

Dudraug
()

Создание множества виртуалок с разными ip

Добрый день, задача такая - надо создать много (100-500) виртуальных контейнеров на одной машине с уникальными ip. Каждый из них будет выполнять наипростейшии задачи - чтение из файла и построчная отправка на один сервак. Я так понимаю тут надо смотреть в сторону xen, docker? Или есть решение более оптимальное? Если не сложно поделитесь сылочками на мануалы.

Спасибо.

 , , , ,

Dudraug
()

Возможно ли задать универсальный лексический анализатор

Всем добрый день!

Допустим есть такой код

this->buf += newPart;
std::vector<std::string> messages = tokenizer.Tokenize(this->buf);

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

Допустим формат мессаги такой

'+'<любые байты кроме контрольных>'-'<два байта контрольной суммы>
сейчас внутри токенайзера используется самописный лексический анализатор, который имеет три выходных состояния - сообщение, мусор, обрубок на конце сообщения.

Все вроде хорошо. Но появилась потребность использовать такую же логику для другого формата сообщений, но формат уже совершенно другой

'!'<любое кол-во латинских символов и цифр>\r\n
Форматы выгледят настолько разными, что нужно или писать отдельный лексический анализатор, либо расширять старый 3 новыми лексемами (сообщение_формат2, мусор2, обрубок2)

А что делать если появится третий формат? Писать 3 анализатор, или добавлять в текущий еще 3 лексемы?

Вариант с расширением существующего выглядит разумным, но это приводет к разрастанию кода и уменьшению читаемости.

Существует ли некий способ быстро и лаконично описать новый лексичский анализатор? Например через regex. Я их конечно использую время от времени, но не то что бы сильно силен в них...

 , , лексический анализ

Dudraug
()

концепции random access iterators

Небольшая предыстория: Имеем проект, который активно использует буст, несколько компиляторов разных версий.

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

В кратце проблема была в использование итераторов возвращаемых make_transform_iterator с функтором возвращаемым значение в boost::algorithm::boyer_moore_search. После замены функтора на функторов возвращающий ссылку все заработало вновь и везде.

Так вот теперь вопрос:

Правильно ли я понимаю, что random access iterator в видение boost не требует того что бы operator* возвращал ссылку, а не значение?

А вот c++ концепция тех же итераторов говорит, что возвращаемы тип должен быть ссылкой.

Или я что-то тут опускаю?

 ,

Dudraug
()

Создание фонового треда на время жизни класса

Идея примерно такая. Есть некоторый класс A в котором есть некоторая струтура данных, допустим мапа. Класс имеет публичные методы работы с этой мапой. Но нам допустим надо запустить фоновый поток который будет в бесконечном цикле проверять, ну допустим насколько запись в мапе стара и удалять ее если надо. Тред должен завершиться вместе с уничтожением класса без ругани и эксепшенов.

Придмал такое решение. Подскажите, если тут подводные камни, или оно нормальное? Естественно, потом туда надо добавить еще мьютексы. Но меня сейчас больше интересует создание и управление этим фоновым тредом

#include <thread>
#include <memory>
#include <map>
#include <iostream>
typedef  std::map<std::string,std::string> MyMap;

class A
{
private:
  class Thread
  {
  private:
    bool flag;
    MyMap& my_map_inst;
    std::thread thr;
  public:

    void funct()
    {
      while (flag) {
        std::cout << "ooo" << std::endl;
      }
      std::cout << "fin" << std::endl;
    }

    Thread(MyMap& m) : flag(true), my_map_inst(m), thr(std::bind(&Thread::funct,this))
    {
    }

    void final()
    {
      flag = false;
      thr.join();
    }

  };

  MyMap my_map_inst;

  Thread thread_i;
public:
  A() : thread_i(my_map_inst)
  {

  }

  ~A()
  {
    thread_i.final();
  }

};

int main()
{

  {
  A a;

  }
  std::cout << "111" << std::endl;

  int i;
  std::cin >> i;
  return 0;
}

По идее проблем быть не должно. Стандарт вроде гарантирует создание мапы до создания объекта треда и инициализацию контрольного флага (flag) до запуска треда. Может тут есть еще какие подводные камни?

 

Dudraug
()

aligned_storage для не-POD

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

Допустим я хочу написать свой optional класс (типо boost::optional)

template<class T>
class optional
{
 ...
public:
 optional(const T& obj) 
 {
   new (storage) T(obj);
   initialized = true;
  }
...
private:
  bool initialized;
  aligned_storage<sizeof<T>, alignof<T>>::type storage;
  

};

В доке написанно

Provides the member typedef type, which is a PODType suitable for use as uninitialized storage for any object whose size is at most Len and whose alignment requirement is a divisor of Align.

Но я пока не могу понять, что мешает использовать такой класс для не-POD объектов. Может я что-то упускаю?

Я знаю, что memcpy для не-POD объекта в буфер (размером sizeof) скорее всего приведет к некорректному объекту. Но тут у нас копирования байтов нет, просто создание нового объекта через конструктор копирования...

 

Dudraug
()

как изменить подписи на оси y

имею такой график созданый через гнуплот https://www.dropbox.com/s/ecji9b2dxzz1swy/Untitled.png?dl=0

Значения входные на оси y были 1 и 0, что собственно и видно на картинке. Но нужно чтобы вместо 1 было написанно On, а вместо 0 Off.

Как возможно сделать такое?

Upd: Проблема состоит в том, что я даже не понимаю как составить запрос к гуглу на мой вопрос...

 

Dudraug
()

RSS подписка на новые темы