LINUX.ORG.RU

Сообщения CyberK

 

Profiler for android native code

Привет, может ли кто посоветовать каким профайлером пользоватся для нативного кода на андроидах? (c++, arm-v7-hardfloat)

 , , , ,

CyberK
()

Окружность относится к кругу как эллипс относится к ... ?

Вопрос математикам и прочим.
Окружность относится к кругу как эллипс относится к ... ?
Так как-же называется участок плоскости ограниченный эллипсом?

 

CyberK
()

c++ gsl don't stay close to hardware

Просто посмотрел тот же самый луп старым способом или при помощи ново рекомендуемого array_view

int sum(int * arr, size_t size)
{
	int result = 0;
	for (int i = 0; i < size; ++i)
		result += arr[i];
	return result;
}

vs

int sum(gsl::array_view<int> arr)
{
	int result = 0;
	for (int & i : arr)
		result += i;
	return result;	  
}
превращается в
	push	ebx
	push	esi
	push	edi

	xor	edi, edi
	mov	ebx, ecx

	xor	esi, esi
	npad	7
$LL4@sum:

	add	edi, DWORD PTR [ebx+esi*4]
	inc	esi
	add	esp, 8
	cmp	esi, 7
	jb	SHORT $LL4@sum

	mov	eax, edi
против
	push	ebp
	mov	ebp, esp
	push	ecx

	mov	eax, DWORD PTR _arr$[ebp]
	mov	ecx, DWORD PTR _arr$[ebp+4]

	push	ebx
	push	esi
	push	edi

	xor	edi, edi

	lea	ebx, DWORD PTR [eax+ecx*4]
	mov	esi, eax
$LL37@sum_arr:

	cmp	esi, ebx

	je	SHORT $LN3@sum_arr

	cmp	esi, eax
	jb	SHORT $LN56@sum_arr
	lea	eax, DWORD PTR [eax+ecx*4]
	cmp	esi, eax
	jae	SHORT $LN56@sum_arr

	add	edi, DWORD PTR [esi]
	mov	ecx, DWORD PTR _arr$[ebp+4]
	add	esp, 8
	mov	eax, DWORD PTR _arr$[ebp]

	add	esi, 4

	jmp	SHORT $LL37@sum_arr
$LN56@sum_arr:

	call	DWORD PTR __imp__terminate
$LN81@sum_arr:
$LN3@sum_arr:

	mov	eax, edi
Сори за интел синтакс, был доступ только к MSVC.

Компу нужно намного дольше работать чтоб получить тот же результат.

P.S. всяким адептам кричащим «c++ с классами это не c++» не лезьте сюда в тред

 , ,

CyberK
()

Оптимизировать использование памяти

Ок, новая головоломка всем адептам ооп, красивого кода и так же всем царями.

Дано: Класс который является адаптером для битовых масок больших размеров - 190 бит. Размер маски определён на этапе компиляции и не изменяется.

На данный момент класс является простой обёрткой над std::bitset (код приведён ниже)

Проблема заключается в данных которые там находятся.

Екземляры данного класса очень коротко живущие и их очень много. (каждые 10мс появляются и уничтожаются десятки тысяч). Количество использованной информации в большинствo из них довольно мало. Большая часть масок состоит из нулей и от одного до пяти активных битов. хотя переодически попадаются и по 30-40 битов. Очень редко могут появлятся почти все заженные биты.

Соотношение полезной информации к используемогу пространству очень и очень низкое.

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

Обязательные условия: 1. Нельзя пользоватся хипом 2. Должен остатся абсолютно тот же интерфейс класса. 3. Как можно более минимальный оверхед на обработку внутрених данных. 4. Нельзя использовать inline asm

Можно использовать любые техники -> от темплейтов до SIMD intrinsics.

Вроде ничего не забыл. Если появятся вопросы - я отвечу.

Ну и сам код класса;

#include <inttypes.h>
#include <assert.h>
#include <bitset>

#define CHANGESET_MAX_BITS 190

class ChangeSet
{
public:
  inline ChangeSet()
  {}

  inline explicit ChangeSet(uint32_t uniqueChangeID)
  {
	//The current implementation of ChangeSet is limited to total 190 changes
    assert(uniqueChangeID < CHANGESET_MAX_BITS);
    m_changes.set(uniqueChangeID, 1);
  }

  inline ChangeSet(const ChangeSet & other): m_changes(other.m_changes)
  {}

  inline void clear()
  {
    m_changes.reset();
  }

  inline bool empty() const
  {
    return m_changes.none();
  }

  inline ChangeSet & operator |=(const ChangeSet & other)
  {
    m_changes |= other.m_changes;
    return *this;
  }

  inline ChangeSet operator |(const ChangeSet & other) const
  {
    ChangeSet out(*this);
    out |= other;
    return out;
  }

  inline void addChanges(const ChangeSet & other)
  {
    m_changes |= other.m_changes;
  }

  inline void removeChanges(const ChangeSet & other)
  {
    m_changes &= ~other.m_changes;
  }

  inline ChangeSet & operator &=(const ChangeSet & other)
  {
    m_changes &= other.m_changes;
    return *this;
  }

  inline ChangeSet operator &(const ChangeSet & other) const
  {
    ChangeSet out(*this);
    out &= other;
    return out;
  }

  inline ChangeSet & operator ^=(const ChangeSet & other)
  {
    m_changes ^= other.m_changes;
    return *this;
  }

  inline ChangeSet operator ^(const ChangeSet & other) const
  {
    ChangeSet out(*this);
    out ^= other;
    return out;
  }

  inline ChangeSet operator ~() const
  {
    ChangeSet out;
    out.m_changes = ~m_changes;
    return out;
  }

  inline operator bool() const
  {
    return !m_changes.none();
  }

  inline bool containsAnyOf(const ChangeSet & other) const
  {
    return !(m_changes &  other.m_changes).none();
  }

  inline bool operator ==(const ChangeSet & other) const
  {
    return m_changes == other.m_changes;
  }

  inline bool operator !=(const ChangeSet & other) const
  {
    return m_changes != other.m_changes;
  }

  static inline ChangeSet generateChangeSetWithAllChangesOn()
  {
    ChangeSet out;
    out.m_changes.flip();
    return out;
  }

private:
  std::bitset<CHANGESET_MAX_BITS> m_changes;
};

 , ,

CyberK
()

Kак ускорить исполнение данного кода?

Есть код, очень - очень медленный, нужно ускорить ну пару хотя-бы раз в 16. конструктор и деструктор не учитываются в бенчмарке Какие есть идеи?

#include <stdlib.h>

struct BallsManager
{
  BallsManager(size_t count);
  ~BallsManager();
  void process();

  float * x;
  float * y;
  float * dir_x;
  float * dir_y;

  size_t m_count;
  float * m_buffer;
};


BallsManager::BallsManager(size_t count):
	m_count(count)
{
  m_buffer = new float[count * 4] ;
  x = m_buffer;
  dir_x = (x + count);
  y = (dir_x + count);
  dir_y = (y + m_count);

  for (size_t i = 0; i < m_count; ++i)
    x[i] = (i % 200) + 5.0f;

  for (size_t i = 0; i < m_count; ++i)
    dir_x[i] = 1.0f;

  for (size_t i = 0; i < m_count; ++i)
    y[i] = (i % 200) + 5.0f;

  for (size_t i = 0; i < m_count; ++i)
    dir_y[i] = 1.0f;
}

BallsManager::~BallsManager()
{
  delete[] m_buffer;
}


void BallsManager::process()
{
  static const float min_x = 0.0f;
  static const float max_x = 640.0f;
  static const float min_y = 0.0f;
  static const float max_y = 480.0f;

  for (size_t i = 0; i < m_count; ++i)
  {
    float curr_x = x[i];
    float curr_y = y[i];
    float curr_dir_x = dir_x[i];
    float curr_dir_y = dir_y[i];

    if (curr_x <= min_x || curr_x >= max_x)
    {
       curr_dir_x = -curr_dir_x;
       dir_x[i] = curr_dir_x;
    }
    x[i] = curr_x + curr_dir_x;

    if (curr_y <= min_y || curr_y >= max_y)
    {
       curr_dir_y = -curr_dir_y;
       dir_y[i] = curr_dir_y;
    }
    y[i] = curr_y + curr_dir_y;
  }
}

int main()
{
  BallsManager bm(15000);

  //-- need to speedup from here --
  for (int iterations = 0; iterations < 1000000; ++iterations)
    bm.process();
  //-- to here --

  return 0;
}

 ,

CyberK
()

Array of structures vs Structure of arrays

Array of structures vs Structure of arrays

Какиe будут ваши за и против?

struct User
{
  int id;
  int money;
  int something;
  char something_else;
  bool active;
  ...
  ...
  float more_data;
}

std::vector<User*> users;

или

struct UserManager
{
  size_t amount;

  int * ids;
  int * money;
  int * something;
  char * something_else;
  bool * active;
  ...
  ...
  float * more_data;

  void setUserMoney(int uid, int money);
  //etc...
}

 

CyberK
()

MyClass & myObj = otherObj;

Вопрос C++никам, что вы имеете сказать за или против references (&) ?

Почему иногда поинтеры для передачи данных в функцию лучше?

 

CyberK
()

Быстрая проверка float range на C

Привет всем, вопрос просто по теории, допустим у меня есть

float a = 1.0f;
float min = 20.0f;
float max = 100.221f
bool in_range = ((min <= a) && (a <= max));
А есть ли еще быстрые способы проверки нахождения числа в диапазоне?

CyberK
()

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