Недавно я выяснил, что использование новое размещение быстрее, чем выполнение 16 назначений:
Рассмотрим следующий кусок кода (C ++ 11): < /p>
class Matrix
{
public:
double data[16];
Matrix() : data{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }
{
};
void Identity1()
{
new (this) Matrix();
};
void Identity2()
{
data[0] = 1.0; data[1] = 0.0; data[2] = 0.0; data[3] = 0.0;
data[4] = 0.0; data[5] = 1.0; data[6] = 0.0; data[7] = 0.0;
data[8] = 0.0; data[9] = 0.0; data[10] = 1.0; data[11] = 0.0;
data[12] = 0.0; data[13] = 0.0; data[14] = 0.0; data[15] = 1.0;
};
};
< /code>
Использование: < /p>
Matrix m;
//modify m.data
m.Identity1(); //~25 times faster
m.Identity2();
На моей машине Identity1 () примерно в 25 раз быстрее, чем вторая функция. А теперь мне любопытно, почему есть такая большая разница?void Identity3()
{
memset(data, 0, sizeof(double) * 16);
data[0] = 1.0;
data[5] = 1.0;
data[10] = 1.0;
data[15] = 1.0;
};
< /code>
Но это даже медленнее, чем Identity2 () < /code>, и я не могу представить, почему. < /p>
Информация о профилировании < /h2>
Я сделал несколько тестирования профилирования, чтобы увидеть, является ли это проблемой, связанной с профилированием, так что есть неверные тестирование, но также не тестируют, но также не тестируются, но и тестирование, но и тестирование. /> Метод профилирования 1: (хорошо известный тест цикла) < /p>
struct timespec ts1;
struct timespec ts2;
clock_gettime(CLOCK_MONOTONIC, &ts1);
for (volatile int i = 0; i < 10000000; i++)
m.Identity(); //use 1 or 2 here
clock_gettime(CLOCK_MONOTONIC, &ts2);
int64_t start = (int64_t)ts1.tv_sec * 1000000000 + (int64_t)ts1.tv_nsec;
int64_t elapsed = ((int64_t)ts2.tv_sec * 1000000000 + (int64_t)ts2.tv_nsec) - start;
if (elapsed < 0)
elapsed += (int64_t)0x100000 * 1000000000;
printf("elapsed nanos: %ld\n", elapsed);
< /code>
Метод 2: < /p>
$ valgrind --tool=callgrind ./testcase
$ # for better overview:
$ python2 gprof2dot.py -f callgrind.out.22028 -e 0.0 -n 0.0 | dot -Tpng -o tree.png
< /code>
Информация об сборке < /h2>
Как пользователь T.C. Указано в комментариях, это может быть полезно: < /p>
код на gcc.godbolt.org < /p>
компиляция и информация о машине < /h2>
Скомтилирован с: g ++ -st = c ++ 11- -Wall
-pg не проблема. Получил одинаковую дифференциацию времени в методе измерения 1 без использования этого флага. < /P>
< /blockquote>
Machine info (lscpu):
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 58
Model name: Intel(R) Core(TM) i7-3612QM CPU @ 2.10GHz
Stepping: 9
CPU MHz: 2889.878
CPU max MHz: 3100.0000
CPU min MHz: 1200.0000
BogoMIPS: 4192.97
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 6144K
NUMA node0 CPU(s): 0-7
Подробнее здесь: https://stackoverflow.com/questions/322 ... assignment
Почему размещение новое гораздо быстрее, чем прямое задание? ⇐ C++
Программы на C++. Форум разработчиков
-
Anonymous
1749125710
Anonymous
Недавно я выяснил, что использование новое размещение быстрее, чем выполнение 16 назначений:
Рассмотрим следующий кусок кода (C ++ 11): < /p>
class Matrix
{
public:
double data[16];
Matrix() : data{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }
{
};
void Identity1()
{
new (this) Matrix();
};
void Identity2()
{
data[0] = 1.0; data[1] = 0.0; data[2] = 0.0; data[3] = 0.0;
data[4] = 0.0; data[5] = 1.0; data[6] = 0.0; data[7] = 0.0;
data[8] = 0.0; data[9] = 0.0; data[10] = 1.0; data[11] = 0.0;
data[12] = 0.0; data[13] = 0.0; data[14] = 0.0; data[15] = 1.0;
};
};
< /code>
Использование: < /p>
Matrix m;
//modify m.data
m.Identity1(); //~25 times faster
m.Identity2();
На моей машине Identity1 () примерно в 25 раз быстрее, чем вторая функция. А теперь мне любопытно, почему есть такая большая разница?void Identity3()
{
memset(data, 0, sizeof(double) * 16);
data[0] = 1.0;
data[5] = 1.0;
data[10] = 1.0;
data[15] = 1.0;
};
< /code>
Но это даже медленнее, чем Identity2 () < /code>, и я не могу представить, почему. < /p>
Информация о профилировании < /h2>
Я сделал несколько тестирования профилирования, чтобы увидеть, является ли это проблемой, связанной с профилированием, так что есть неверные тестирование, но также не тестируют, но также не тестируются, но и тестирование, но и тестирование. /> Метод профилирования 1: (хорошо известный тест цикла) < /p>
struct timespec ts1;
struct timespec ts2;
clock_gettime(CLOCK_MONOTONIC, &ts1);
for (volatile int i = 0; i < 10000000; i++)
m.Identity(); //use 1 or 2 here
clock_gettime(CLOCK_MONOTONIC, &ts2);
int64_t start = (int64_t)ts1.tv_sec * 1000000000 + (int64_t)ts1.tv_nsec;
int64_t elapsed = ((int64_t)ts2.tv_sec * 1000000000 + (int64_t)ts2.tv_nsec) - start;
if (elapsed < 0)
elapsed += (int64_t)0x100000 * 1000000000;
printf("elapsed nanos: %ld\n", elapsed);
< /code>
Метод 2: < /p>
$ valgrind --tool=callgrind ./testcase
$ # for better overview:
$ python2 gprof2dot.py -f callgrind.out.22028 -e 0.0 -n 0.0 | dot -Tpng -o tree.png
< /code>
Информация об сборке < /h2>
Как пользователь T.C. Указано в комментариях, это может быть полезно: < /p>
код на gcc.godbolt.org < /p>
компиляция и информация о машине < /h2>
Скомтилирован с: g ++ -st = c ++ 11- -Wall
-pg не проблема. Получил одинаковую дифференциацию времени в методе измерения 1 без использования этого флага. < /P>
< /blockquote>
Machine info (lscpu):
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 58
Model name: Intel(R) Core(TM) i7-3612QM CPU @ 2.10GHz
Stepping: 9
CPU MHz: 2889.878
CPU max MHz: 3100.0000
CPU min MHz: 1200.0000
BogoMIPS: 4192.97
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 6144K
NUMA node0 CPU(s): 0-7
Подробнее здесь: [url]https://stackoverflow.com/questions/32223377/why-is-a-placement-new-much-faster-than-a-direct-assignment[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия