Если нужен голый алгоритм, то вот он: "1234" = ((((0*10)+1)*10+2)*10+3)*10+4 Если нужно 64 битное умножение в вб, то называй тему соответственно, зачем отнимать время
Забить на VB что ли? Всё равно я им только как большим калькулятором пользуюсь Ну и ActiveX разве что для 1С-ки написать.
LZNT1 Реализовывать математику больших чисел на VB... Это автоматически на 3-5 порядков снижает скорость выполнения кода (в лучшем случае), иными словами на 386@30Mhz ассемблерный алгоритм будет куда быстрее, чем на P4@3000Mhz "реализованный" на VB. Если прикидывать - порядка 0.1 (но скорее всего больше) сек на одно число. Кошмар, я тут недавно переписал (даже не оптимизировал) один конвертер сделанный в Excel, на C++. До было (при одинаковом большом наборе данных) - 6 минут, а после - 4 секунды (на iCel@2405). Юзабилити налицо.
Кстати, alpet попробуй этот аттач, насколько он стабильно показывает результаты (разброс по итерациям) У меня получаются такие разбросы: --------------------------- Тест из 10 проходов Код (Text): --------------------------- TICKS ~= 00000000000000047482 TICKS ~= 00000000000000005686 TICKS ~= 00000000000000005631 TICKS ~= 00000000000000005651 TICKS ~= 00000000000000005636 TICKS ~= 00000000000000005613 TICKS ~= 00000000000000005611 TICKS ~= 00000000000000005605 TICKS ~= 00000000000000005567 TICKS ~= 00000000000000005561 825176896___rdtsc.zip
TICKS ~= 00000000000000055656 TICKS ~= 00000000000000021092 TICKS ~= 00000000000000020792 TICKS ~= 00000000000000019708 TICKS ~= 00000000000000019944 TICKS ~= 00000000000000019744 TICKS ~= 00000000000000019860 TICKS ~= 00000000000000020060 TICKS ~= 00000000000000019592 TICKS ~= 00000000000000019568 [warn-fix] if (CreateWindowEx(...)); // <- точку с запятой убрал... hButton = CreateWindowEx(...) [question] Что за интересный компилер, что не поддерживает int64?
Не понял, почему не поддерживает? Компилятор M$ vc++ 7.10.3077 (от 2003) Сейчас поменял __int64 x[4] на double x[4] - также работает.
cresta Это я к тому что у тебя счетчики состоят из двух половинок. Неудобно вроде. Да и инлайновое оформление rdtsc лучше наверное функцией оформить (правда компилер может ее и не встроить, если задать просто inline).
вон ты о чём, да с двордами удобнее после rdtsc из eax:edx забирать значения, потому так и осталось два дворда. А про инлайн, не понял, поясни. Вроде ж написал void inline Init_Clock(). Или это не инлайн? Не встраивается по месту вызова?
cresta Погоди, вроде результат __int64 по соглашению __stdcall итак выдается в edx:eax. Т.е. функция выглядит так: <font face="fixedsys] __int64 __stdcall _rdtsc () { __asm { xor eax, eax cpuid rdtsc } } } </font><!--face--> Кстати собственное время Init_Clock() - порядка 2000 тактов. Почему так долго? Насчет inline - мелкомягкие перемудрили опять, дескать их компилятор умный и сам решает встраивать или нет, но если уж очень надо %100 - нужно указывать __forceinline. Можно также в начале программы указать: //#ifndef __forceinline //#define __forceinline inline //#endif #define inline __forceinline
Чё - то я не пойму, ты какой исходник смотришь? Если test_proc() изменить вот так: Код (Text): Init_Clock(); //запуск счётчика // посредине пусто, нет ничего, тестируется только счетчик Stop_Clock();//останов счётчика wsprintf (temp, "TICKS ~= %.10lu%.10lu \n", dwStartH, dwStartL); strcat (buffer, temp); то мессаджбокс выдаёт нули на все 10 проходов, т.к. в Init_Clock() учитывается время на опрос самого счётчика и затем вычитается из результата. Специально для этого служат две переменные CounterL и CounterH, в которых и записывается время, которое необходимо на опрос счётчика. А в Stop_Clock() значение времени корректируется (из показаний счётчика вычитается CounterL и CounterH, т.е. время, необходимое на саму инициализацию и опрос счётчика). Так что откуда 2000 - не ясно. Инлайн посмотрел в отладчике - вписывает по месту вызова, никаких call, именно как макрос в асме.
А про _stdcall: мне из функции не надо забирать значения счетчика, оно прямо в функции сохраняется в глобальные переменные dwStartL и dwStartH. Потому Init_Clock() и Stop_Clock() и void сделал.
cresta 1. Нет-нет, все верно - результат работы Init_Clock правильный, я просто не понял что в ней так долго выполняется, cpuid что-ли... 2. Да с этими инлайнами у меня путаница оказывается (пока еще нераспутал): The __forceinline keyword overrides the cost/benefit analysis and relies on the judgment of the programmer instead. Exercise caution when using __forceinline. Indiscriminate use of __forceinline can result in larger code with only marginal performance gains or, in some cases, even performance losses (due to increased paging of a larger executable, for example). ... The inline keyword is available only in C++. The __inline and __forceinline keywords are available in both C and C++. For compatibility with previous versions, _inline is a synonym for __inline.
а, понял: почему сама Init_clock() выполняется так долго? Чёрт знает, почему, все-таки cpuid не самая быстрая инструкция. У меня она тянет на 66 тиков. К тому же для правильной инициализации cpuid и rdtsc выполняются по несколько раз, потому и набегает время. Но в любом случае, сколько бы сама функция не выполнялась, это время учитывается и конечный результат получается реальный.
alpet Не нужно путать интерпретатор VBA с компилятором VB6. В математических и целочисленных операциях он (VB6) выдаёт такую же скорость как и VC, потому как в конечном итоге они используют один и тот же компилятор. Ну и потом, что за конвертер? Он небось читает из ячеек таблицы, а ты небось строки из памяти?
LZNT1 Даже VB можно заставить генерить ассемблерные листинги, объектники, оптимизируй сгенеренный ним листинг и перекомпиль или сделай .obj из асмовой процедуры и линкуй её в VB
LZNT1 Ну компилятор еще можно юзать, но сравнивать его с C++ по части оптимзации не стоит. По части конвертора - он выбирал чисела из таблицы до накопления некоторой суммы, полученный диапазон значений записывал в другую таблицу. В программе на C++ таблицы нет - массив чисел, он его он получал из текстового буфера (числа разделенные пробелами/табуляциями/CRLF). Оно то и понятно что интерпретация вещь жутко тормозная, по сравнению с скомпилированным и оптимизированным кодом (тем более если под CLR). Но всеже имхо VB не сильно подходит под решение задач на скорость, хотя допускаю что путем долгих мучений можно родить вполне сносный алгоритм преобразования больших целых.
bogrus Для VB статическая линкова слишком сложна чтобы ей просто было воспользоваться. Необходимы сторонние утилиты, перехватывающие сообщения Си-шному компилятору. Вобщем этот алгоритм (MUL) для VB не подходит, хотя решение очень хорошее. alpet Почему не стоит если VB6 компилирует с помощью адаптированного компилятора C++ (C2.EXE)? Такая огромная разница в скорости между VBA и C++ получилась скорее из за скорости получения данных из таблицы (COM), чем из за тормознутости VBA. Возьми ради интереса создай COM-клиента(экселя) на С++ и попробуй осуществить выборку элементов в цикле. С массивом и VBA я думаю неплохо справится. Кстати вызывов машинных кодов через CallWindowProc в VBA ещё никто не отменял.
LZNT1 В большинстве случаев программист на C++ закладывает основу оптимизации программы - помогая компилятору, так что продукт вторичной обработки едва-ли будет хорошо оптимизирован. Впрочем я это не проверял, поэтому только предполагаю о более лучших результатах компиляции C++ кода написанного вручную (при условии грамотности писателя). Насчет тормознутости VBA cпорить не буду, поскольку не особо разбираюсь где и что в нем узкое место. Просто привык считать всю ввасиковую платформу достаточно узкоспециализированной (т.е. на нем решают те задачи под которые он и разрабатывался). Через CallWindowProc конечно можно, но это что-то из разряда использования PEEK/POKE в Spectrum Basic'e: нужен быстрый код - выбери соответствующий язык и компилятор/ассемблер. Подозреваю что для борьбы с большими числами более всего бы сгодился Intel Fortran Compiler. У тебя кстати какой критерий привязанности к VB в данной задаче?
alpet Всей программы - да, не спорю. Но я смотрел пару прог VB-шных и оптимизирует он довольно умно (если это слово вообще уместно к ЯВУ-шному компилятору). По поводу CallWindowProc, зачем PEEK/POKE? Берёшь свой любимый ассемблер, пишешь что тебе нужно, ассемблируешь, грузишь ассемблированный бинарник в память и передаешь ему управление с помощью CallWindowProc. "Просто привык считать всю ввасиковую платформу достаточно узкоспециализированной." Не согласен. Бейсик - это исключительно для начинающих и решать серьёзные задачи на нём вообще не стоит. Особенно на VB. У меня просто привычка. Для меня это как родной язык программирования. Вообще мне PB хватает с головой. Там и беззнаковые числа и указатели и Inlnie assembler. "У тебя кстати какой критерий привязанности к VB в данной задаче?" Исследовательский дух, ничего более. Где можно качнуть этот Intel Fortran Compiler?
LZNT1 1. Опять же это надо использовать скорее странности, чем свойства языка. 2. Некоторым профессионалам (хотя серьезные задачи они на нем не решают конечно) он все-таки нравится, мне вот уже давно разонравился. 3. Компиляторы Intel можно с их сайта закачать, но потом придется преодолевать ограничение trial-лицензии (лекарство в инете должно быть).