|
|
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Всем доброго времени суток! Существуют ли программисты, помнящие ASM? )) Столкнулись с проблемой: в Delphi нет подобной функции, есть IntToStr, но на выходе string. В большом проекте нужен именно PChar. На С++ это itoa, atoi. Сделал костыль из стандартной IntToStr путём комментирования функции задела строки и дёргаю в наглую после выхода из неё по указателю шмат памяти: Код: pascal 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. Тоже самое для int64 и overlode. Если кому пригодиться, могу скинуть для int64. Функцию __CvtInt тоже пришлось перетянуть из сорцов делфи). Мне не понравилось это решение. Нашёл 2 исходника на асм по такой же задаче для int и int64, единственное - использовались регистры ax,bx,cx... и т д. и генерился 16 битный код. Могу скинуть также оба исходника и ссыль на них. Так вот суть вопроса: найденая вставочка int в дельфе отрабатывает на ура, быстрее чем костыльный вариант. Но с int64 возникли трудности. я не мастер asmа, но чую не так я записываю в стек или перемещаю указатель. Вот исходник со статьи: Код: pascal 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. Моя переделка заключалась в замене всех основных регистров на 32х битные, то есть ax на eax, bx на ebx и т д. так как 16 битный дельфа строить отказывается. Если надо скину переделку. Дельфа зацикливается при делении числа на 10 и записи остатка. Пока стек не кончится)) где я косячу? Данный код работает в asm - проверял. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 18:36 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
компилятор дельфи такой страшный код генерит, что на асме писать нужно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 18:53 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Нет) Можно и обойтись средствами Делфи. Важна скорость, это ключевой момент. большие объёмы данных, много расчётов. Поэтому прибегли к АСМ. Для примера нагрузочных тестов 100 000 000 преобразований на каждом ядре: Функциями дельфи - профит -0,38, процент скорости - 30% Костыльный вариант - профит +0,75, процент скорости - 81% Самодел из взятых исходников - профит -0,95, процент скорости - 90% Это если чисто int. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 19:02 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90Но с int64 возникли трудности. я не мастер asmа, но чую не так я записываю в стек или перемещаю указатель. Дельфи x64 использует Microsoft's Win64 calling convention соответственно первые 4 параметра - RCX,RDX,R8,R9 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 19:29 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Спасибо за инфу, но немного не то. Речь идёт о Delphi x32 (Delphi 7). Судя по их исходникам с asm в те года 64е регистры были мечтой) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 20:08 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90, так где лыжи не едут - в x86 ? что надо то - int64 в pchar? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 20:20 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Да, всё верно. Лыжи не ежут в старой Delphi 7, в асмовой вставке int64ToPChar. IntToPChar сработала на ура, сложностей не было - число ложится в регистр как есть. int64ToPChar - не как есть, как я понял это указатель в стеке, или не указатель, инфы не нарыл. видать из за этого я не правильно кладу старшую и младшую части, и из за этого соответственно кривит сам цикл деления на 10 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 20:44 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90int64ToPChar - не как есть, как я понял это указатель в стеке, или не указатель, инфы не нарыл. видать из за этого я не правильно кладу старшую и младшую части, и из за этого соответственно кривит сам цикл деления на 10 какой бы мусор на регистры не попал - зацикливаться ничего не должно, на выходе максимум 19 цифр. а команда div у интела изрядно косая. ничего хорошего из лобового деления edx:eax на 10 не получится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 21:40 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
сколь неприятна процедура деления int64 на x86 - можно увидеть - http://www.jbox.dk/sanos/source/lib/lldiv.asm.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.01.2017, 21:52 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Мысль понял, спасибо за совет!) Буду курить данный пример. Ещё раз благодарю за отзывчивость! Но вот кстати!) В исходных сорцах Делфи 7 похожий алгоритм на тот, что я нарыл. За исключением что я в стек кидаю остатки, а там как я понял в память сразу пишут. Но тоже div)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 00:20 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90, 1. Вместо деления но 10 можно умножать на обратный. 2. Вместо деления на 10 можно делить на 100 и брать из таблицы сразу 2 цифры. 3. Можно длинное число разбить на 2 куска и разбираться с каждым отдельно. 4. Можно срисовать код с современной Delphi и не мучиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 00:27 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90, может сначала попробовать Pascal-код? Код: pascal 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. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. Если скорость не устроит, тогда уже переписывать на ассемблере. Изопропилкомпилятор дельфи такой страшный код генерит, что на асме писать нужно?Если Delphi-йский компилятор для кода типа «n mod 10 ... n div 10» генерирует 2 инструкции div, то да :). Aleksandr Sharahov3. Можно длинное число разбить на 2 куска и разбираться с каждым отдельно.Мне удалось разбить только на 3 части. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 07:52 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Пётр СедовЕсли Delphi-йский компилятор для кода типа «n mod 10 ... n div 10» генерирует 2 инструкции div, то да :). если немного подумать, а не переводить стрелки на компилятор, то легко понять, что есть алгоритм с одним делением: d:=n div 10; r:=n - d * 10; Пётр СедовМне удалось разбить только на 3 части. если проявить смекалку, например, перейти к беззнаковым числам и поработать со старшими битами и с обратными числами, то удается получить 2 части. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 09:10 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Пётр Седов Код: pascal 1. 2. этого можно избежать изначально заполнив весь буфер нулями ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 11:15 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Aleksandr Sharahovесли проявить смекалку многое можно сделать - без делений в цикле обойтись, например. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 11:48 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
ИзопропилAleksandr Sharahovесли проявить смекалку многое можно сделать - без делений в цикле обойтись, например. Можно пример как обойтись вообще без делений в цикле? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 12:25 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Пётр Седов, Благодарю! Примерно тоже самое и было сперва на дельфях писано, медленно) Но идея разбить на 2 куска и вызвать процедурку для простого уже intа - мне кажется будет выигрышной. Главное не запутаться с переходящим, дёрнуть заранее знак и склеить в конце 2 массива и их длины. сегодня попробую, вечером кину код) Всех благодарю за советы! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 12:26 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Dima TИзопропилпропущено... многое можно сделать - без делений в цикле обойтись, например. Можно пример как обойтись вообще без делений в цикле? поделить можно один раз, а затем умножать Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. дальше - переход к фиксированной точке, разделение на группы и т д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 13:27 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Не работает, погрешности преобразования double мешают Код: sql 1. Тест Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 13:42 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Если погрешность добавить, то вроде работает Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 13:51 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Преобразования double-int тоже не легкая операция. Затестил время, деление целых почти вдвое быстрее. Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 14:13 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Ребята не гоните коней))) вещественные не нужны) и есть функция в дельфях вроде FloatToPChar если не ошибаюсь)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 14:27 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Dima T, я же сразу сказал, что это только направление, реально нужно на фиксированную точку перевести придётся сделать )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 14:29 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Dima TМожно пример как обойтись вообще без делений в цикле? 1. Заменить деление умножением, умножать на обратный. 2. Заменить деление вычитанием, делить в столбик. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 15:05 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Aleksandr Sharahov1. Заменить деление умножением, умножать на обратный. Путаешь. Вычитание можно заменить на сложение с обратным, но к делению это неприменимо. Aleksandr Sharahov2. Заменить деление вычитанием, делить в столбик. Быстрее не станет, слишком много операций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 15:12 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
На похмельную голову вышло как-то так: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Сама IntToText(та самая самоделка): Код: pascal 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. Погонял на числах, вроде работает. По скорости отпишу после 9го числа, все тесты на работе) Всем спасибо за советы! Код ещё в порядок надо будет привести и сделать owerlode, но это мелочи. Ещё раз благодарен всем за помощь! и с прошедшими и наступающими) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 15:20 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Dima TAleksandr Sharahov1. Заменить деление умножением, умножать на обратный. Путаешь. Вычитание можно заменить на сложение с обратным, но к делению это неприменимо. Не путаю. 1. Можно погуглить на тему "замена целочисленного деления умножением" или глянуть Уоррена, например. 2. Можно посмотреть, во что преобразует деление на 10 любой сишный компилятор. 3. До кучи тут есть немного http://guildalfa.ru/alsha/node/31 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 15:22 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Midgard90, внезапно переполнение: val : int64; n : integer; n := val div 1000000000; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 15:45 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Посмотрел во что мой код скомпилировался, похоже компилятор MSVС сам заменил деление Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 16:11 |
|
||
|
IntToPChar на 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. аргумент беззнаковый, на выходе лидирующие нули ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 16:37 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Странно) скорее всего старая дельфа топорная, потому как в их исходниках IntToStr похожий код с делением, что на выходе в асме не смотрел, но работает. В новой всё заменено уже сями и fastcall, да и работать в новой проще. Насчёт переполнения думаю не проблема, разбить не на 2 а на 4 части и каждую прогнать, потом сложить PCharы. Конечный вариант кину после 9го) работы для праздников хватит)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.01.2017, 16:39 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
погонял. переполнения не встретил. приведи пример? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 02:09 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Aleksandr SharahovПётр СедовЕсли Delphi-йский компилятор для кода типа «n mod 10 ... n div 10» генерирует 2 инструкции div, то да :). если немного подумать, а не переводить стрелки на компилятор, то легко понять, что есть алгоритм с одним делением: d:=n div 10; r:=n - d * 10;Деление, умножение, вычитание. Три операции в машинном коде. При том, что достаточно одной, потому что x86-инструкция div выдаёт 2 результата: частное (в регистре eax) и остаток (в регистре edx), и хороший оптимизирующий компилятор должен этим пользоваться. Ну это как для кода «cos(x) ... sin(x)» генерировать одну инструкцию fsincos. Или для кода «(n << 16) | (n >> 16)» генерировать одну инструкцию циклического сдвига. А так-то понятно, что руками много чего можно сделать, например беззнаковое деление на степень двойки заменить на битовый сдвиг. Aleksandr SharahovПётр СедовМне удалось разбить только на 3 части. если проявить смекалку, например, перейти к беззнаковым числам и поработать со старшими битами и с обратными числами, то удается получить 2 части.int64 (максимум 19 цифр) можно разбить на 3 части (9 цифр, 9 цифр, 1 цифра) или на 4 части (5 цифр, 5 цифр, 5 цифр, 4 цифры). А на 2 части как разбить? (чтобы каждая часть гарантированно влезала в 32 бита) ИзопропилПётр Седов Код: pascal 1. 2. этого можно избежать изначально заполнив весь буфер нулямиДа, но длинные последовательности нулей редко встречаются, так что этим особо не ускоримся. Изопропил Код: plaintext 1. Проверил, работает правильно. Пара мелочей: Изопропил Код: plaintext 1. Похоже, не нужно. Если работаем со строками в C-шном стиле, то хорошо бы писать завершающий нулевой char: Код: plaintext 1. 2. 3. 4. 5. Я переписал ваш код на Pascal: Код: pascal 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. 117. 118. 119. 120. 121. 122. 123. 124. 125. Midgard90погонял. переполнения не встретил. приведи пример?Ваш код: Midgard90 Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Если value = val = 9223372036854775807 (максимальное значение), то: val div 1000000000 = 9223372036 -- не влезает в integer (максимальное значение -- 2147483647). И в cardinal тоже не влезает (максимальное значение -- 4294967295). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 05:21 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Пётр СедовДеление, умножение, вычитание. Три операции в машинном коде. При том, что достаточно одной, потому что x86-инструкция div выдаёт 2 результата: частное (в регистре eax) и остаток (в регистре edx) Ты же понимаешь, что мое замечание касалось ненужности второго деления в твоем коде? И компилятор тут ни при чем. На самом деле не нужно и первое деление. Или нужно, но другое. Пётр Седовint64 (максимум 19 цифр) можно разбить на 3 части (9 цифр, 9 цифр, 1 цифра) или на 4 части (5 цифр, 5 цифр, 5 цифр, 4 цифры). А на 2 части как разбить? (чтобы каждая часть гарантированно влезала в 32 бита) Идея в том, чтобы отделить часть работы, которая формально соответствует очень маленькой третьей части данных, и выполнить эту часть работы независимо от обработки двух других больших кусков. Ну, когда, например, мы обрабатываем знак числа, мы же не называем это третьей частью данных, хотя формально так оно и есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 09:22 |
|
||
|
IntToPChar на 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. быстрее, чем библиотечный _ui64toa глядя на ассемблерное порождение - сильно больше на 32 бит x86 - вряд ли получится выжать Код: sql 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. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 11:33 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Еще можно itoa и atoi собрать в obj файл на с++ и затем использовать в проекте на Delphi. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 22:43 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
__Avenger__в obj файл на с++ что означает этот набор слов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 23:21 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Изопропил__Avenger__в obj файл на с++ что означает этот набор слов? Скомпилировать c++ файл в obj файл, а затем использовать его в delphi через директиву {$LINK *.obj}. ZLib так например в дельфи подключен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 23:27 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
__Avenger__Изопропилпропущено... что означает этот набор слов? Скомпилировать c++ файл в obj файл, а затем использовать его в delphi через директиву {$LINK *.obj}. ZLib так например в дельфи подключен. ну лучше С, а не С++ и внимательно следить чтоб из рантайма лишку не зацепить. проще dll сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2017, 23:46 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Изопропил Код: plaintext 1. 2. 3. 4. Код: sql 1. 2. 3. 4. 5. 6. 7. Visual C++ сгенерировал такой код, как предлагал Aleksandr Sharahov: деление, умножение, вычитание. Хотя вполне мог сгенерировать код типа: edx:eax ← _vq div 100000 v3 ← eax (частное) v2 ← edx (остаток) Изопропил Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... глядя на ассемблерное порождение - сильно больше на 32 бит x86 - вряд ли получится выжатьТут одинаковые операции делаются, поэтому если писать на ассемблере, то можно попытаться ускориться за счёт использования MMX-инструкций, которые работают с 32-битными числами, упакованными в 64-битные регистры: paddd -- делает параллельно два сложения psubd -- делает параллельно два вычитания pslld -- делает параллельно два битовых сдвига влево psrld -- делает параллельно два битовых сдвига вправо pand -- делает параллельно два битовых and (на самом деле, просто 64-битный and) А вот умножения нормального нет, поэтому умножение на f1_10001 придётся делать обычными инструкциями, а умножение на 10 заменить на «(n << 3) + (n << 1)». Кстати, Visual C++ умножение на 10 делает так: Изопропил Код: sql 1. 2. Изопропил Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Зачем Visual C++ делает «ecx ← buf + 19» на каждой итерации цикла? Это достаточно сделать один раз до цикла. А если писать на ассемблере самому, то тут вообще, насколько я понимаю, весь цикл можно записать одной инструкцией: repe scasb. Изопропилбыстрее, чем библиотечный _ui64toaКруто. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 06:57 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Пётр СедовVisual C++ сгенерировал такой код, как предлагал Aleksandr Sharahov: деление, умножение, вычитание. Хотя вполне мог сгенерировать код типа: edx:eax ← _vq div 100000 v3 ← eax (частное) v2 ← edx (остаток) uint64/uint32 - частное может не уместиться в uint32, потому нельзя одной командой, переполнение может случиться - потому - деление "столбиком" (см исходники ulldiv.asm, ulldrvm.asm) Пётр СедовЗачем Visual C++ делает «ecx ← buf + 19» на каждой итерации цикла? inc и lea выполнятся одновременно, потери производительности не будет, хотя действительно странно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 09:49 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
SSE2 версия Код: 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. не ускоряет ( по крайней мере на тех CPU, что использовал) а что до "крутости" - _ui64toa работает с произвольным основанием системы счисления и скорость зависит от количества цифр, возня может иметь смысл, если часто преобразовывать большие числа приходится. в конечном итоге - преобразование двоичного в десятичное вряд ли является узким местом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 10:08 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Если нужно обрабатывать многоцифр, то нужно их обрабатывать параллельно. И добро пожаловать в волшебный мир SIMD. Остальное пырхание не стоит внимания. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 10:10 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
SiemarglИ добро пожаловать в волшебный мир SIMD. он не настолько волшебен, как иногда кажется. ускорь _ui64toa с помощью SSE4, а там и будем выводы делать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 11:07 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Таак... с переполнением разобрался, потом нашёл ещё несколько багов: прошлая функция не дописывала нули, например: 9000000001000000001 на выходе 911)). В общем вышло как-то так: Код: pascal 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. Не думаю теперь что она быстрее IntToStr или предложенной ранее чисто дельфийской)) Завтра на скорость будем тестить с профитом по ядрам. Как её укоротить или оптимизировать уже что-то не соображаю. И масса локальных напрягает. Не функция а костыль, но работает)) Если есть мысли, с удовольствием выслушаю, как её сделать красивши) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 14:10 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Да, забыл, IntToText() осталась прежней, чисто асемблер, как и кидал ранее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 14:12 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
ИзопропилSiemarglИ добро пожаловать в волшебный мир SIMD. он не настолько волшебен, как иногда кажется. ускорь _ui64toa с помощью SSE4, а там и будем выводы делатьТы не понял идею. Нужно не одно число переводить, а пачку. Т.е. _ui64toa(const uint64_t val[4],.....) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 15:40 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
Siemargl, у интела в SIMD уже появилось деление 64 битных целых ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 15:56 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
ИзопропилSiemargl, у интела в SIMD уже появилось деление 64 битных целых ?Эмм, не нашел. Там простого деления я совсем не наблюдаю, только алгоритмами. Но оно не требуется. Нам нужно деление с остатком 64бит на 32бит. Оно реализуется 32-битными операциями, например так div_s64_rem() http://lxr.free-electrons.com/source/lib/div64.c ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 22:04 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
SiemarglНам нужно деление с остатком 64бит на 32бит. Оно реализуется 32-битными операциями, например так div_s64_rem() а SIMD каким боком тогда? вариация на тему _ui64toa получается что касается реализации деления в msvc для x86 - деление - _aulldvrm (msvc runtime, ветка для короткого делителя нас интересует) Код: 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. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. и _aulldiv (остаток восстанавливать в вызывающем коде) Код: 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. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. беда в том,что самая затратная операция в алгориме - деление ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2017, 22:19 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
ИзопропилПётр СедовVisual C++ сгенерировал такой код, как предлагал Aleksandr Sharahov: деление, умножение, вычитание. Хотя вполне мог сгенерировать код типа: edx:eax ← _vq div 100000 v3 ← eax (частное) v2 ← edx (остаток) uint64/uint32 - частное может не уместиться в uint32,Да, но в коде: Изопропил Код: plaintext 1. 2. 3. 4. нужно не всё частное, а только младшие 32 бита этого частного. Изопропилпотому нельзя одной командой, переполнение может случитьсяЯ тут почитал, оказывается инструкция div возбуждает исключение в случае переполнения (если частное не влезает в 32 бита), вот поэтому компилятор и не может её здесь использовать. Но если заверить компилятор, что частное влезает в 32 бита: Код: plaintext 1. 2. то может и будет использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2017, 05:59 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
ИзопропилSiemarglНам нужно деление с остатком 64бит на 32бит. Оно реализуется 32-битными операциями, например так div_s64_rem() а SIMD каким боком тогда? вариация на тему _ui64toa получается Нет. Пусть у нас есть функция func(x:64-bit), и мы ее будем вызывать для многих x, foreach(x: {}) func(x). Тогда векторизация ее выглядит так func(x[4]) { все операции с x заменяются на соответствующие векторные с x[4] } Конечно, это придется сделать со всеми вызываемыми функциями из func(), в том числе, заменить intrinsic деления, что весьма муторно. В общем, вот желающим матаппарат, а для меня задача имеет решение, но подробности в данный момент неинтересны, и просто пое-ься я тоже не хочу =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2017, 11:38 |
|
||
|
IntToPChar на ASM для DELPHI
|
|||
|---|---|---|---|
|
#18+
SiemarglВ общем, вот желающим матаппарат, а для меня задача имеет решение, для меня тоже имеет решение, беда в том что оно весьма вероятно окажется менее производительным, чем со скалярными операциями. ну а попытка сегодня писать подобное на x86, а не на x64 - странна как то. А написанное выше - просто разминка для мозга и повод освежить в памяти систему команд интела и интринсики Интел ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2017, 12:02 |
|
||
|
|

start [/forum/topic.php?all=1&fid=16&tid=1340523]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
139ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
98ms |
get tp. blocked users: |
1ms |
| others: | 259ms |
| total: | 542ms |

| 0 / 0 |
