Опять выравнивание
От: Аноним  
Дата: 11.10.05 11:50
Оценка:
Есть код:

выдает при pack(1) — 61,5 * 10^6
push,1 — 60 * 10^6
по умолчанию — 62 * 10^6

Получается что без выравнивания работает медленне чем с. С чего бы это? Получается штрафов нет за выранивание по байту?

#include "stdafx.h"
#include "windows.h"

#pragma pack(1) //(push,1)//
struct s
{
  char c1;
  int  i1;
  char c2;
  long l1;
  int  i2;
  long l2;
};
#pragma pack() // pop()//

///////////////////////////////////////////////////////////////////////////////
//CPU Usage function

_int64 FileTimeToQuadWord( PFILETIME pft ) 
{ 
   return( Int64ShllMod32(pft->dwHighDateTime, 32) | pft->dwLowDateTime ); 
}

int GetCPUUsage()
{
  FILETIME ftCreationTime; 
  FILETIME ftExitTime; 
  FILETIME ftKernelTime; 
  FILETIME ftUserTime;
  
          _int64 qwCpuUsageTime;
  static  _int64 qwCpuUsageLastTime;
  static  _int64 qwLastTS;
          _int64 qwTS = GetTickCount();
  static  int    iCPUUsage;

  if ( ( qwTS - qwLastTS ) > 500 )
  {
    GetProcessTimes(GetCurrentProcess(), &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
    
    qwCpuUsageTime      = FileTimeToQuadWord(&ftKernelTime) + FileTimeToQuadWord(&ftUserTime); 
    
             
    iCPUUsage           = (int)((qwCpuUsageTime - qwCpuUsageLastTime)) ;/// ((qwTS - qwLastTS) * 100)) ;  // ns / ms
  
    qwCpuUsageLastTime  = qwCpuUsageTime;
    qwLastTS            = qwTS; 
  }

  return iCPUUsage;
}

int _tmain(int argc, _TCHAR* argv[])
{
  s obj_s;
  obj_s.c1 = 1;
  obj_s.c2 = 2;
  obj_s.i1 = 3;
  obj_s.i2 = 4;
  obj_s.l1 = 5;
  obj_s.l2 = 6;
  
  GetCPUUsage();
  for(_int64 i = 0; i < 1000000000; i++)
  {
    long l = obj_s.c1 + obj_s.c2 + obj_s.i1 + obj_s.i2 + obj_s.l1 + obj_s.l2;
  }

  printf("CPU usage: %i", GetCPUUsage());
  scanf("%i",&i);
  return 0;
}
Re: Опять выравнивание
От: Erop Россия  
Дата: 11.10.05 12:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть код:


А>
А>  for(_int64 i = 0; i < 1000000000; i++)
А>  {
А>    long l = obj_s.c1 + obj_s.c2 + obj_s.i1 + obj_s.i2 + obj_s.l1 + obj_s.l2;
А>  }

А>

А ты во что это компилится смотреть не пробовал?
Но вообще так говоря, вычисляемое в цикле выражение должно бы выносить за цикл, а там наверное и вообще херится, в силу своей ненужности.
Так что при чём тут выравнивание -- знают только кишки компиллера
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Опять выравнивание
От: Аноним  
Дата: 11.10.05 13:57
Оценка:
Здравствуйте, Erop, Вы писали:

E>А ты во что это компилится смотреть не пробовал?

E>Но вообще так говоря, вычисляемое в цикле выражение должно бы выносить за цикл, а там наверное и вообще херится, в силу своей ненужности.
E>Так что при чём тут выравнивание -- знают только кишки компиллера

Внуть не лазил, времени нет, но проверялось с отключенной оптимизацией, так что разворачивать не должен был!
Re[3]: Опять выравнивание
От: Erop Россия  
Дата: 11.10.05 14:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Внуть не лазил, времени нет, но проверялось с отключенной оптимизацией, так что разворачивать не должен был!


Тогда тем более результаты произвольными могли оказаться
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Опять выравнивание
От: _Winnie Россия C++.freerun
Дата: 11.10.05 14:10
Оценка:
Прикол. Если написать
for(_int64 i = 0; i < 1000000000; i++)
то компилятор не выкидвыет бесмысленный цикл.
А если
for(int i = 0; i < 1000000000; i++)
то выкидывает. Я это связываю с тем, что "i++" и "i<1000000000" когда i — __int64 это тяжёлая библиотечная функция, про которую компилятор не может сказать, есть в ней side effects или нет.


А код long l = obj_s.c1 + obj_s.c2 + obj_s.i1 + obj_s.i2 + obj_s.l1 + obj_s.l2; вообще выкидывается.

Ты меряешь не скорость сложения, а скорость цикла(который по причине выше компилятор забыл выкинуть.)

Померяем правильно. Что бы не ловить баги еще и в твоих функция измерения времени, я из выкинул.

C выравниванием:
CPU usage: 720

Без него:
CPU usage: 860

Код:
#include "stdio.h"
#include "windows.h"

//#pragma pack(1) //(push,1)//
struct s
{
  char c1;
  int  i1;
  char c2;
  long l1;
  int  i2;
  long l2;
};
//#pragma pack() // pop()//

//то, что переменные глобальные, это важно, иначе оптимизатор их воообще выкинет.
s array[100]; //небольшой массив, что бы не умереть в page fault.
long l; 

int main(int argc, char* argv[])
{
  DWORD x = GetTickCount();

  //int а не __int64, иначе мы меряем скорость библиотечной функции сравнения __int64 с чилом и прибавления единицы
  for(int i = 0; i < 10000000; i++)
  {
      for (int j=0; j<100; ++j)
      {
          ::l = array[j].c1 + array[j].c2 + array[j].i1 + array[j].i2 + array[j].l1 + array[j].l2;
      }
  }

  printf("CPU usage: %i", GetTickCount()-x);
  return 0;
}
Правильно работающая программа — просто частный случай Undefined Behavior
Re[2]: Опять выравнивание
От: Erop Россия  
Дата: 11.10.05 14:20
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>
_W>s array[100]; //небольшой массив, что бы не умереть в page fault.
_W>


Забавно то, что если таки массив сделать большим, то станет важно какой объём данных качается в память и в кэш проца. Ну и тогда уже может так статься, что невыровненные, но более компактные данные обрабатываются быстрее.

Скажем, если выравненные в кэш не помещаюся, а невыровнянные -- таки помещаются, то скорее всего результат однозначно бкдет в сторону невыровненных
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Опять выравнивание
От: Аноним  
Дата: 11.10.05 15:26
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>А код long l = obj_s.c1 + obj_s.c2 + obj_s.i1 + obj_s.i2 + obj_s.l1 + obj_s.l2; вообще выкидывается.


При отключенной оптимизации?
Произвол!

_W>Померяем правильно. Что бы не ловить баги еще и в твоих функция измерения времени, я их выкинул.

Я мерял не время, а тики процессора, что на многозадачной ОС, имхо, правильнее!

Кстати, может кто попинает функцию измерения загрузки CPU?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.