|
|
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Изначально есть массив array[0..63] of Byte допустим, в каждой ячейке хранится число 3 есть переменная типа Int64, какие-то биты, которой, заполнены 1-ей, какие-то 0-м как бы быстро раскидать эти биты по соотв. ячейкам массива (просуммировать) чтобы получить соотв-нно 4-ки в ячейках куда попали биты с единицами ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 00:31:29 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
сдвиг 1 на разряд и логическое умножение с числом... Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 00:56:53 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Я не силен в Delphi, но вот вроде бы работает правильно: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 11:29:14 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Vowk , впечатляет - в ДВА раза быстрее, чем мой корявый вариант, при этом даже если обращаться к массиву через указатели - то же самое: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 13:21:52 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Да, существенная разница в скорости. Получается, что расширение ASM в Delphi имеет определенный смысл и вполне работоспособно, а я смотрел на эту особенность как на прикол какой-то. Возможно скорость еще можно повысить, если использовать 64-битный сдвиг, просто команду не помню. Если Delphi её поймет, то можно избавиться от одного цикла. По поводу packed принял к сведению - важная деталь, мною упущенная :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 14:24:14 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
VowkВозможно скорость еще можно повысить, если использовать 64-битный сдвиг, просто команду не помню Да. Было бы интересно сравнить :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 16:04:04 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Vowk, молодой человек, ну зачем же было делать такое макраме из кода? Посмотрите, у Вас же там одни переходы. Да и к тому же сканирование просто аховое, есть ведь же BSF, BTR и ADC. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 16:32:28 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Mozok, ну я сразу предупредил, что не претендую на безукоризненность :) Спасибо за замечания, про BSF, BTR и ADC посмотрю информацию, а также подумаю над тем, как обойтись без операторов перехода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 17:00:03 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Vowk> Возможно скорость еще можно повысить, если использовать 64-битный сдвиг, просто команду не помню. Если Delphi её поймет, то можно избавиться от одного цикла. Эта команда набирается из нескольких команд. Сдвигается верхний 32 бит регистр, младьший бит в флаге переноса, а потом сдвигается младьшие 32 бит, а старший бит ставится из флага переноса. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 17:23:29 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Еще вариант. Берем чуть другой алгоритм, пишем (на С, но это неважно) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Компилируем с включенной оптимизацией. Смотрим что получается и дооптимизируем руками, если получается (а тут немножко есть лишнего) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. Переносим в Дельфи. Обратите внимание, что компилер все, что можно, засунул в регистры и используется всего одна косвенная операция. Когда пишешь сам, регистры считать ну очень неудобно, особенно на x86. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 17:36:39 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Вот еще пара ремарок: 1. Когда смотришь ассемблерный код, становится понятно, как поправить оригинал, чтобы скомпилилось более эффективно. 2. Когда (давно) я смотрел на код, который генерит Дельфи - отторжений не вызывало, оптимизатор был вполне на уровне. Так что может быть и не нужно писать на ассемблере (когда нужны инструкции SIMD = MMX итп - исключение), а вот смотреть - обязательно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 17:49:28 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Vowk, вот, набросал на досуге. Честно скажу, сам не проверял. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 18:31:16 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Mozok, Есть вложенный цикл - уже плохо. И похоже с ошибками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 18:41:12 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Siemargl, нет, ну так же совсем никуда не годится :). Компилятор увидел, что х помещается в DWORD и оставил обработку только младших битов. А Вы попробуйте сделать x = 0xFFFFFFFFFFFF и посмотрите, что он нагенерит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 18:43:11 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Siemargl Есть вложенный цикл - уже плохо. Да будет Вам, 2 цикла исключительно из-за загрузки следующего DWORD'а. Если у Вас есть более оптимальный вариант, не дублируя код, предложите. А вот переходов у меня уже на 1 меньше. SiemarglИ похоже с ошибками. Вполне вероятно, говорю же, по-быстрому набросал. А где именно похоже на ошибку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 18:54:08 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Mozok, Тут похоже на ошибку Код: plaintext 1. 2. У меня все верно (вернее у С компилятора) long long == int64. Еще под отладчиком я прогнал - проверил. Нужен желающий погонять скорость на одной машине )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 19:06:38 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
SiemarglMozok, Тут похоже на ошибку Код: plaintext 1. 2. Это защита на случай, если бит с номером 0 равен 1. Loop же сначала декрементит ECX, а потом уже сравнивает его с 0. Без инкремента ЕСХ стал бы равен в этом случае 2^32 - 1 вместо нуля и было бы сделано 2 лишних прыжка. Siemargl У меня все верно (вернее у С компилятора) long long == int64. Еще под отладчиком я прогнал - проверил. Нужен желающий погонять скорость на одной машине )) Не-не-не, так не пойдет :). Вы лучше вложите-ка сгенерированный ассемблерный код для случая, когда x = 0xFFFFFFFFFFFF (или еще лучше, когда значение х задается с консоли). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 19:18:45 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Однако да, недоглядел, что константу оптимизатор использует. Меняем, заодно и подоптимизировал Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 19:18:55 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Блин, опять константу вычислил ( Все. Вызываю с параметром от random << 32 + random; Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 19:34:52 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Siemargl2. Когда (давно) я смотрел на код, который генерит Дельфи - отторжений не вызывало, оптимизатор был вполне на уровне. Проверял первый вариант, предложенный Vowk, в сравнении с моим извращенным на делфи: с {$OPTIMIZATION OFF} asm 4ss, вариант на Delphi - 7ss c {$OPTIMIZATION ON} asm 2ss, вариант на Delphi - 5ss Грустно, что не силен в asm - даже перенести не могу в делфи толком то, что предложил Siemargl :( Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. не знаю что за ll _memset - закоментарил ибо ругается :/ Delphi[Error] Unit1.pas(110): Undeclared identifier: 'll' переходы с SHORT тоже не вкуривает - short убрал Код: plaintext Delphi[Error] Unit1.pas(126): Invalid register combination ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 21:34:43 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
если закоментарить Код: plaintext Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.01.2010, 21:43:27 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Раскидыватель, По Вашем примеру, убираем первый "add esp, 12" - он лишний. call memset - закомментили и ладно (это вызов обнуления массива) Можно убрать весь кусок, относящийся к обнулению, т.е. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Адресация там чуть другая используется. Пробуем править под синтаксис asm-delphi и без memset Ожидаем на стеке один параметр функции типа int64 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2010, 14:03:04 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Siemargl , что-то я растерялся малость... Попробовал скомпилировать на другой машине с вкл/выкл оптимизацей на ней получается, что вариант на Delphi быстрее предложенных на ASM, правда в твой asm я не понял как обращаться к моему массиву, поэтому, конечно, это некорректно сравнивать, но все равно все три варианта если что: Попробуй скомпилрованный экзешник запустить на машине, где при компиляции не важно с оптимизайцией или без вариант на Delphi работает медленнее. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2010, 16:06:44 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
тсПопробуй скомпилрованный экзешник запустить... хотел сказать, попробую ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2010, 16:08:14 |
|
||
|
Раскидать 64 бит по 64 байтам в ASM (Delphi)
|
|||
|---|---|---|---|
|
#18+
Наврал. У меня ошибка в варианте Delphi потому и быстрее - я в цикле 10 млн раз просто инициализирую массив а разбивку делаю всего один раз. Сделал как надо - вариант с ASM по-прежнему миним в два раза быстрее. Только как сделать, чтобы вариант с Siemargl работал именно с массивом ar и именно только цикл разбивки - инициализация пусть на делфи остается для одинаковых условий сравнения первого и второго варианта ASM ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2010, 16:36:12 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=36408186&tid=1343944]: |
0ms |
get settings: |
8ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
215ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
81ms |
get tp. blocked users: |
1ms |
| others: | 225ms |
| total: | 569ms |

| 0 / 0 |
