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
()

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

 ,

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

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

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
()