Сейчас на форуме: tyns777, zds, JustLife (+4 невидимых)

 eXeL@B —› Программирование —› самый быстрый memcpy
<< . 1 . 2 .
Посл.ответ Сообщение

Ранг: 47.1 (посетитель), 2thx
Активность: 0.030
Статус: Участник

Создано: 15 февраля 2010 19:08 · Поправил: Vol4ok
· Личное сообщение · #1

Протестируйте на предмет самой быстрой реализации memcpy -бэнчмэк

В нем содержится множество различных реализаций memcpy начиная от SSE заканчивая простым циклом. Заодно это отличный способ оценить скорость работы с памятью на компе.

Результаты кидайте сюда, вместе с процом на котором тестировали.

Мои результаты для Core2Duo 2.26
Code:
  1. buffer size = 16777216 Bytes
  2. number of copy operation = 16
  3. preparing...
  4. start!
  5.  
  6. // MMX реализация на асме с prefetch
  7. mmx_memcpy_asm:
  8. ttl: 0.114444 s
  9. avr: 0.007153 s
  10. spd: 2237 mb/s
  11.  
  12. // MMX реализация на intrinsic инструкциях c prefetch
  13. mmx_memcpy:
  14. ttl: 0.115609 s
  15. avr: 0.007226 s
  16. spd: 2214 mb/s
  17.  
  18. // очень хитрая на MMX под AMD c prefetch
  19. memcpy_huge:
  20. ttl: 0.111493 s
  21. avr: 0.006968 s
  22. spd: 2296 mb/s
  23.  
  24. //реализация на SSE
  25. sse_memcpy_asm:
  26. ttl: 0.177681 s
  27. avr: 0.011105 s
  28. spd: 1441 mb/s
  29.  
  30. //реализация на SSE c prefetch
  31. sse_memcpy_asm2:
  32. ttl: 0.143008 s
  33. avr: 0.008938 s
  34. spd: 1790 mb/s
  35.  
  36. //реализация на SSE на intrinsic инструкциях
  37. sse_memcpy:
  38. ttl: 0.183768 s
  39. avr: 0.011486 s
  40. spd: 1393 mb/s
  41.  
  42. //реализация на SSE на intrinsic инструкциях без выравнивания
  43. sse_memcpy_u:
  44. ttl: 0.189657 s
  45. avr: 0.011854 s
  46. spd: 1350 mb/s
  47.  
  48. //цикл rep movsd
  49. movsd:
  50. ttl: 0.181586 s
  51. avr: 0.011349 s
  52. spd: 1410 mb/s
  53.  
  54. //ntdll RtlCopyMemory
  55. RtlCopyMemory:
  56. ttl: 0.200333 s
  57. avr: 0.012521 s
  58. spd: 1278 mb/s
  59.  
  60. //crt memcpy_s
  61. memcpy_s:
  62. ttl: 0.207848 s
  63. avr: 0.012990 s
  64. spd: 1232 mb/s
  65.  
  66. //цикл for c копированием по 4B
  67. for loop (dword):
  68. ttl: 0.204562 s
  69. avr: 0.012785 s
  70. spd: 1251 mb/s
  71.  
  72. //цикл while c копированием по 4B
  73. while loop (dword):
  74. ttl: 0.197684 s
  75. avr: 0.012355 s
  76. spd: 1295 mb/s
  77.  
  78. //цикл while c копированием по 1B
  79. for loop (byte):
  80. ttl: 0.276843 s
  81. avr: 0.017303 s
  82. spd: 925 mb/s
  83.  
  84.  

ЗЫ: если есть еще идеи для реализации быстрой memcpy, то кидайте сюда, если это будет актуально то включу в бэнчмэк.



Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 16 февраля 2010 14:56
· Личное сообщение · #2

Vol4ok пишет:
второй тест измеряет время при помощи rdtsc - что менее точно чем QueryPerfomanceCounter

С каких соображений? Одно на втором базируется.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 16 февраля 2010 15:04
· Личное сообщение · #3

cppasm пишет:
С каких соображений?

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

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 49.6 (посетитель), 9thx
Активность: 0.030
Статус: Участник

Создано: 16 февраля 2010 15:20
· Личное сообщение · #4





Ранг: 47.1 (посетитель), 2thx
Активность: 0.030
Статус: Участник

Создано: 16 февраля 2010 15:25 · Поправил: Vol4ok
· Личное сообщение · #5

cppasm пишет:
С каких соображений? Одно на втором базируется.

К тому что сказал ntldr могу добавить, что rdtsc - плох на мультипроцессорных системах, так как число тактов отличается на разных процессорах, непонятно, учитывал ли автор этой программы это обстоятельство.
QueryPerfomanceCounter к rdtsc никакого отношения не имеет - он работает на основе системного таймера, встроенного в материнскую плату, который генерирует прерывания, через определенный интервал (на современных компах < 1 нс).



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 16 февраля 2010 16:54
· Личное сообщение · #6

По поводу таймеров советую прочитать:www.insidepro.com/kk/030/030r.shtml

-----
продавец резиновых утёнков




Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 16 февраля 2010 17:09
· Личное сообщение · #7

Можно попробовать вызвать SetThreadIdealProcessor для получения более достоверных результатов с rdtsc.

-----
Shalom ebanats!




Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 16 февраля 2010 17:31
· Личное сообщение · #8

software.intel.com/en-us/articles/measure-code-sections-using-the-enhanced-timer/

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 65.3 (постоянный), 10thx
Активность: 0.020
Статус: Участник

Создано: 16 февраля 2010 19:16
· Личное сообщение · #9

Core2Duo E8500@3.7Ghz
Code:
  1. buffer size = 16777216 Bytes
  2. number of copy operation = 16
  3. preparing...
  4. start!
  5.  
  6. mmx_memcpy_asm:
  7. ttl: 0.070954 s
  8. avr: 0.004435 s
  9. spd: 3608 mb/s
  10.  
  11. mmx_memcpy:
  12. ttl: 0.070385 s
  13. avr: 0.004399 s
  14. spd: 3637 mb/s
  15.  
  16. memcpy_huge:
  17. ttl: 0.071167 s
  18. avr: 0.004448 s
  19. spd: 3597 mb/s
  20.  
  21. sse_memcpy_asm:
  22. ttl: 0.105238 s
  23. avr: 0.006577 s
  24. spd: 2433 mb/s
  25.  
  26. sse_memcpy_asm2:
  27. ttl: 0.082380 s
  28. avr: 0.005149 s
  29. spd: 3108 mb/s
  30.  
  31. sse_memcpy:
  32. ttl: 0.105768 s
  33. avr: 0.006611 s
  34. spd: 2420 mb/s
  35.  
  36. sse_memcpy_u:
  37. ttl: 0.112650 s
  38. avr: 0.007041 s
  39. spd: 2273 mb/s
  40.  
  41. movsd:
  42. ttl: 0.102461 s
  43. avr: 0.006404 s
  44. spd: 2499 mb/s
  45.  
  46. RtlCopyMemory:
  47. ttl: 0.102289 s
  48. avr: 0.006393 s
  49. spd: 2503 mb/s
  50.  
  51. memcpy_s:
  52. ttl: 0.104459 s
  53. avr: 0.006529 s
  54. spd: 2451 mb/s
  55.  
  56. for loop (dword):
  57. ttl: 0.108781 s
  58. avr: 0.006799 s
  59. spd: 2353 mb/s
  60.  
  61. while loop (dword):
  62. ttl: 0.109561 s
  63. avr: 0.006848 s
  64. spd: 2337 mb/s
  65.  
  66. for loop (byte):
  67. ttl: 0.154765 s
  68. avr: 0.009673 s
  69. spd: 1654 mb/s




Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 16 февраля 2010 20:45
· Личное сообщение · #10

s0l пишет:
Со второго теста:

Rustem пишет:
со второго


а мужики то не знают (с) что MessageBox по Ctrl-C копируется в буфер : )



Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 16 февраля 2010 20:47
· Личное сообщение · #11

какие-то читерские у вас процы, что получается у некоторых movsd быстрее =)



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 16 февраля 2010 21:00
· Личное сообщение · #12

SLV пишет:
Можно попробовать вызвать SetThreadIdealProcessor для получения более достоверных результатов с rdtsc.

_____
ntldr пишет:
software.intel.com/en-us/articles/measure-code-sections-using-the-enhanced-timer/

- там как раз и юзается SetAffinityMask

-----
продавец резиновых утёнков





Ранг: 154.2 (ветеран), 66thx
Активность: 0.080
Статус: Участник
REVENGE Crew

Создано: 16 февраля 2010 21:51 · Поправил: kioresk
· Личное сообщение · #13

Core i7 960 3.2 GHz

Code:
  1. buffer size = 16777216 Bytes
  2. number of copy operation = 16
  3. preparing...
  4. start!
  5.  
  6. mmx_memcpy_asm:
  7. ttl: 0.052446 s
  8. avr: 0.003278 s
  9. spd: 4881 mb/s
  10.  
  11. mmx_memcpy:
  12. ttl: 0.053444 s
  13. avr: 0.003340 s
  14. spd: 4790 mb/s
  15.  
  16. memcpy_huge:
  17. ttl: 0.053611 s
  18. avr: 0.003351 s
  19. spd: 4775 mb/s
  20.  
  21. sse_memcpy_asm:
  22. ttl: 0.075181 s
  23. avr: 0.004699 s
  24. spd: 3405 mb/s
  25.  
  26. sse_memcpy_asm2:
  27. ttl: 0.051074 s
  28. avr: 0.003192 s
  29. spd: 5012 mb/s
  30.  
  31. sse_memcpy:
  32. ttl: 0.075208 s
  33. avr: 0.004701 s
  34. spd: 3404 mb/s
  35.  
  36. sse_memcpy_u:
  37. ttl: 0.075351 s
  38. avr: 0.004709 s
  39. spd: 3397 mb/s
  40.  
  41. movsd:
  42. ttl: 0.063070 s
  43. avr: 0.003942 s
  44. spd: 4059 mb/s
  45.  
  46. RtlCopyMemory:
  47. ttl: 0.063159 s
  48. avr: 0.003947 s
  49. spd: 4053 mb/s
  50.  
  51. memcpy_s:
  52. ttl: 0.075127 s
  53. avr: 0.004695 s
  54. spd: 3408 mb/s
  55.  
  56. for loop (dword):
  57. ttl: 0.093235 s
  58. avr: 0.005827 s
  59. spd: 2746 mb/s
  60.  
  61. while loop (dword):
  62. ttl: 0.093701 s
  63. avr: 0.005856 s
  64. spd: 2732 mb/s
  65.  
  66. for loop (byte):
  67. ttl: 0.166334 s
  68. avr: 0.010396 s
  69. spd: 1539 mb/s




Ранг: 47.1 (посетитель), 2thx
Активность: 0.030
Статус: Участник

Создано: 18 февраля 2010 21:57
· Личное сообщение · #14

Итак подведу итоги. Просуммировав все представленные результаты получилась следующий статистика



Лично для себя я сделал следующие выводы (исходя из удобства использования их в своих проектах)

- самая удобная в использовании функа - movsd (и ее ntdll аналог RtlCopyMemory), плюсы в следующем
+ наличие соответствующей интринсик инструкции в компиляторе от МС
+ кросплатформенность (код с movsd будет работать как на х86 так и на х64, без дополнительных изощрений)
+ хорошие показатели скорости, при своей невероятной простоте.
Ее можно использовать в проектах где скорость не является целью.

Если же цель именно скорость то тут 2 фаворита реализация на MMX и SSE, как видно в большинстве случаев MMX работал быстрее, на самом деле я немного поэксперементировав, получил более быструю реализацию, которая сравнима с показателями MMX и даже превышает ее в ряде случаев (все желающий могут дополнительно это протестить в -этом бэнчмэке).
Но к сожалению они не так удобны в использовании как movsd, и не обладают кросплатформеностью, и требуют дополнительных изощрений с выравниванием.
Реализация на MMX - может быть написана на интринсик инструкциях компилятора, но к сожалению не может работать под х64 системой. SSE реализация (в том виде который дает максимальные результаты) - не может быть написана интринсик - и неизбежно использование ассемблера в чистом виде. В моем случае использовался инлайн асм, но он не актуален для х64 бита систем, так что придется иметь дополнительный гимор и подшивать асм файлики для каждой платформы к проекту (в данном случае я подразумеваю использования мелкософтного компилятора). Однако те кто пользуются компилятором intel - думаю что SSE реализация на интринсик возможна, таким образом можно безболезнено вставлять эту реализацию в свои проекты не боясь проблем с компиляцией под разные платформы.

Вот мои реализации обеих процедур (буфера должны быть выравнены по 64Б)

MMX
Code:
  1. void mmx_memcpy(char *dst, char *src, size_t len)
  2.  
  3. {
  4.  
  5.          __m64 t1, t2, t3, t4;
  6.          __m64 t5, t6, t7, t8;
  7.  
  8.          while (len >= 64) {
  9.  
  10.                  _mm_prefetch((char *)(src + 0x40),_MM_HINT_NTA);
  11.  
  12.                  t1 = *(__m64 *)(src +  0);
  13.                  t2 = *(__m64 *)(src +  8);
  14.                  t3 = *(__m64 *)(src + 16);
  15.                  t4 = *(__m64 *)(src + 24);
  16.                  t5 = *(__m64 *)(src + 32);
  17.                  t6 = *(__m64 *)(src + 40);
  18.                  t7 = *(__m64 *)(src + 48);
  19.                  t8 = *(__m64 *)(src + 56);
  20.  
  21.                  _mm_stream_pi((__m64 *)(dst +  0), t1);
  22.                  _mm_stream_pi((__m64 *)(dst +  8), t2);
  23.                  _mm_stream_pi((__m64 *)(dst + 16), t3);
  24.                  _mm_stream_pi((__m64 *)(dst + 24), t4);
  25.                  _mm_stream_pi((__m64 *)(dst + 32), t5);
  26.                  _mm_stream_pi((__m64 *)(dst + 40), t6);
  27.                  _mm_stream_pi((__m64 *)(dst + 48), t7);
  28.                  _mm_stream_pi((__m64 *)(dst + 56), t8);
  29.  
  30.                  src += 64; dst += 64; len -= 64;
  31.          }
  32.  
  33.          _mm_empty();
  34.  
  35. }


SSE (более крутая версия, а не та чтобы в первом тесте)
Code:
  1. void sse_memcpy_asm2(char *dst, char *src, size_t len)
  2.  
  3. {
  4.  
  5.          __asm{
  6.  
  7.                  mov        ecx, [len]    
  8.                  mov        edx, [dst]   
  9.                  mov        eax, [src]   
  10.                  align      16
  11.  
  12. cpy:
  13.                  prefetchnta     [eax+0x80]
  14.  
  15.                  movdqa xmm0,xmmword ptr [eax] 
  16.                  movdqa xmm1,xmmword ptr [eax+10h]
  17.                  movdqa xmm2,xmmword ptr [eax+20h]
  18.                  movdqa xmm3,xmmword ptr [eax+30h]
  19.  
  20.                  movntps         xmmword ptr [edx],xmm0 
  21.                  movntps         xmmword ptr [edx+10h],xmm1
  22.                  movntps         xmmword ptr [edx+20h],xmm2
  23.                  movntps         xmmword ptr [edx+30h],xmm3
  24.  
  25.                  add       edx,0x40
  26.                  add       eax,0x40
  27.                  sub       ecx,0x40
  28.                  jnz       cpy
  29.  
  30.          }
  31.  
  32. }


Напоследок хотесь бы сказать немного "хорошего" о мелкософте который очередной раз лажанулся.
Во первых это CRT. Дело в том что CRT реализация - использует SSE, но как видено в большинстве случаев movsd работает быстрее - и поэтому CRT реализация является неэффективной, и соответственно бесполезной. Какой смысл было выпендриваться SSE интрукциями, если они не дает оправданных результатов? Если бы они написали код который я представил выше - было бы куда круче. Также хочу отметить говеную реализацию интринсик инструкций, дело в том, что для того чтобы написать реализацию SSE на интринсик - не хватает всего одной интринсик инструкции - movntps (которая вцелом имеется но не в том виде котором нужно). Мало таго, "порадовала" их идиоцкая оптимизация - если откомпилять код на интринсик инструкциях - то они будут не в том порядке как в оригинале, нафига спрашивается переставлять? этот эффект можно наблюдать на суммарных результатах, как видно MMX реализация на асме в итоге выиграла, только потому что мелкософт влез со совей "оптимизацией" в интринсик реализацию, а код по совей сути идентичный.

ЗЫ: спс ntldr за помощь в написании реализаций.



Ранг: 50.0 (постоянный), 31thx
Активность: 0.090.1
Статус: Участник

Создано: 19 февраля 2010 14:21
· Личное сообщение · #15

ntldr пишет:
Частота процессора может изменяться по ходу его работы. rdtsc следует использовать если мы хотим получить число тактов, а время надо мерять через QueryPerfomanceCounter, или на худой конец GetTickCount

Ну и ахинея. В данном случае производительность надо мерять именно в тактах. Время здесь при чем?
Если один код выполнится за 1000 тактов, а другой за 1100 - однозначно время выполнения первого кода будет меньше. Нет никаких причин думать, что при выполнении второго кода частота по каким то причинам будет выше и следовательно время выполнения меньше.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 19 февраля 2010 14:49
· Личное сообщение · #16

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

spinz пишет:
ет никаких причин думать, что при выполнении второго кода частота по каким то причинам будет выше и следовательно время выполнения меньше.

Поздравляю, вы с громким плеском сели в лужу. Гуглите что такое Intel Turbo Boost, и не учите жить людей, занимающихся оптимизацией побольше вас.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 50.0 (постоянный), 31thx
Активность: 0.090.1
Статус: Участник

Создано: 19 февраля 2010 15:14
· Личное сообщение · #17

ntldr пишет:
Уважаемый spinz, меряйте производительность своего кода хоть в слонах и попугаях, но не учите нас жить. Да будет вам известно, что производительность копирования данных в памяти зависит не только от процессора, но и, как не странно, от скорости работы памяти, в следствии чего эффективность пакетного чтения удобнее считать в мегабайтах в секунду, а не непонятно как скачущих тактах процессора. К тому же, если речь заходит об измерении скорости работы параллельных алгоритмов, то растактовка становиться бесполезной чуть менее, чем полностью.

Послушайте не надо подменять предмет дискусии. Невзирая на скорость памяти - если первый код закончит работу через 1000 тактов, а второй через 1100 - значит первый код закончит свое выполнение раньше. Посему rdtsc здесь самый точный способ замера производительности.

ntldr пишет:
Поздравляю, вы с громким плеском сели в лужу. Гуглите что такое Intel Turbo Boost, и не учите жить людей, занимающихся оптимизацией побольше вас.

Про турбобуст я знаю не хуже вашего. Попробуйте мне объяснить - почему код1 и код2, выполняющиеся на одном ядре при прочих равных условиях, будут выполняться (хотя бы теоретически) при разных тактовых частотах?



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 19 февраля 2010 15:49
· Личное сообщение · #18

spinz пишет:
Невзирая на скорость памяти - если первый код закончит работу через 1000 тактов, а второй через 1100 - значит первый код закончит свое выполнение раньше.

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


spinz пишет:
Попробуйте мне объяснить - почему код1 и код2, выполняющиеся на одном ядре при прочих равных условиях, будут выполняться (хотя бы теоретически) при разных тактовых частотах?

Вот вам краткий список причин:

1 - Мы работаем в многозадачной ОС, а значит работа турбобуста зависит от нагруженности других ядер чужим кодом. Другие ядра нагружены - частота нашего ядра снижается.
2 - Есть такая штука, как гипертрединг, т.е. одно ядро может исполнять 2 потока одновременно. Представьте себе, что в то время, пока наш поток ждет доставки данных из памяти, другой поток исполняется на том же ядре, и турбобуст повышает его частоту.
3 - Процессор может уменьшать свою частоту при перегреве (тротлинг). На скорости работы с памятью это может не сказаться. Влияет даже в однозадачной среде.
4 - Процессор может засыпать на короткое время при низкой нагрузке, соответственно такты не считаются, пока идет ожидание получения данных. Особенно актуально для ноутбучных процессоров и влияет на растактовку даже в однозадачной среде.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 50.0 (постоянный), 31thx
Активность: 0.090.1
Статус: Участник

Создано: 19 февраля 2010 16:09
· Личное сообщение · #19

Я указывал - "при прочих равных условиях", что исключает влияние вышеперечисленных причин.
Про процы и память - я думал очевидно, что речь идет о замерах rdtsc на одной машине. Такты естественно не могут служить критерием быстродействия вообще, 100 тактов на пне1 и 200 тактов на коре-и7, немного разные вещи )))
Вообще подобные тесты производительности весьма неточно отражают ситуацию вне зависимости от методики измерения. Для точного замера надо исключить влияние ОС и многопроцовости. Те же мегабайты в секунду могут быть совсем другими, когда другое ядро к примеру имеет кучу промахов кэша.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 19 февраля 2010 16:22
· Личное сообщение · #20

spinz пишет:
Я указывал - "при прочих равных условиях", что исключает влияние вышеперечисленных причин.

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

spinz пишет:
Про процы и память - я думал очевидно, что речь идет о замерах rdtsc на одной машине.

Речь идет об одной машине. Допустим, что у меня быстрый проц и медленная память (пример - платформа на Core i5 с одной планкой памяти). Мне хотелось бы померять как быстро идет копирование памяти, а не сколько пустых тактов простаивает проц при доступе к ней.

spinz пишет:
Для точного замера надо исключить влияние ОС и многопроцовости.

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

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 19 февраля 2010 17:12 · Поправил: cppasm
· Личное сообщение · #21

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

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

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




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 19 февраля 2010 17:34
· Личное сообщение · #22

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



Ранг: 47.1 (посетитель), 2thx
Активность: 0.030
Статус: Участник

Создано: 19 февраля 2010 18:19
· Личное сообщение · #23

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

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



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 19 февраля 2010 18:35
· Личное сообщение · #24

cppasm пишет:
Так это и будет тот самый сферический конь.Время копирования памяти включает в себя время ожидания доступа к ней.

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

cppasm пишет:
Если исключить влияние изменения тактовой частоты

Можно отключить гипертрединг, турбобуст, энергосбережение, и мерять исключительно из-под доса, но зачем? Если в ТЗ проекта не написано "сделать только так, и никак иначе", то я волен выбирать оптимальные способы под конкретную задачу.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 19 февраля 2010 20:16 · Поправил: cppasm
· Личное сообщение · #25

Vol4ok пишет:
И еще, крайне бессмысленно пытаться учить людей, что и как им делать, особенно в тех случаях когда об этом не просят и очень-очень особенно когда эти люди четко знают как им лучше это сделать.

По-моему никто никого не учил. Хотя вам виднее.
А если так нравится придалбываться к мелочам, то я тоже умею
Vol4ok пишет:
QueryPerfomanceCounter к rdtsc никакого отношения не имеет - он работает на основе системного таймера, встроенного в материнскую плату, который генерирует прерывания, через определенный интервал (на современных компах < 1 нс).

Период в 1нс это тактовая частота 1/10^-9=10^9Hz=1GHz
Если прерывания будут сыпать с такой частотой, система только их и обрабатывать будет.
У HPET (High Precision Event Timer) частота максимальная 10MHz.
Vol4ok пишет:
Если вас так сильно интересует измерение производительности в тактах, то было бы куда полезней сесть и написать свой бэнчмэк, протестировать и представить результаты, а не разводить бестолковый флуд.

Результаты будут аналогичные (в относительных величинах).
ToBad пишет:
Вспомните недавнюю тему, где была программа для сопряжения с девайсом на ком порту управляющая форсунками. На мобильных платформах есть конкретный баг с замером через rdtsc.

Нету там никаких багов.
На мобильных платформах широко используется изменение тактовой частоты в зависимости от нагрузки, отсюда и проблемы.
Мерять надо нормально, понимая что меряешь.
А прога та не работала, потому что нечего задержки делать вида for(i=0;i<0x100000;i++);
Ясно что на разных процессорах (разных поколениях) время выполнения будет очень разное.

Вообще в статье на которую ссылку давал HiEndsoft всё правильно написано, точнее не скажешь:
Некоторые используют в качестве таймера команду RDTSC, считывающую показания внутреннего счетчика процессора, каждый такт увеличивающегося на постоянную величину (как правило, единицу).
Для профилировки машинного кода она подходит на ура, но вот на роль беспристрастного метронома уже не тянет.
Некоторые APCI-контроллеры динамически изменяют частоту процессора или усыпляют его в паузах между работой для лучшего охлаждения.
Как следствие - непосредственное преобразование процессорных тактов в истинное время оказывается невозможным.




Ранг: 47.1 (посетитель), 2thx
Активность: 0.030
Статус: Участник

Создано: 19 февраля 2010 21:54 · Поправил: Vol4ok
· Личное сообщение · #26

cppasm пишет:
По-моему никто никого не учил. Хотя вам виднее.

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

cppasm пишет:
А если так нравится придалбываться к мелочам, то я тоже умею
период в 1нс это тактовая частота 1/10^-9=10^9Hz=1GHz
Если прерывания будут сыпать с такой частотой, система только их и обрабатывать будет.
У HPET (High Precision Event Timer) частота максимальная 10MHz.

я говорил это на основании показателя частоты QueryPerformanceFrequency, который на моем компе равна 2 256 360 000, откуда один период составляет 4,43e-10с. Для моих измерений достаточно точности даваемой QueryPerformanceCounter даже если он будет с частотой 100KHz, на худой конец это легко можно проверить увеличив размер буфера - в моем случае результаты оставались прежними. Я не могу понять что вы мне этим хотели показать? Ваше умение "придалбываться к мелочам" не соответствует содержанию данной темы.

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


<< . 1 . 2 .
 eXeL@B —› Программирование —› самый быстрый memcpy
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати