Страница 1 из 1

Ассемблерные вставки в Си++

Добавлено: 18 янв 2014, 19:31
Полевой
В один прекрасный, солнечный, не предвещавший ничего дурного денек я решил написать простенький код для замера количества тактов, потребных на выполнение некой операции (по факту - обработку исключения).

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

Код: Выбрать все

#include <iostream>
using namespace std;
int main()
 {

 long long t1=0,t2=0;
 long long delta_t=0;

 __asm("CPUID"); // "out-of-order"
 __asm("RDTSC");

 __asm("mov DWORD %PTR[t1], %eax");
 __asm("mov DWORD %PTR[t1 + 4], %edx");


 //Здесь выполняется код, время исполнения которого и замеряется


 __asm("CPUID");
 __asm("RDTSC");
 __asm("movl DWORD %PTR[t2], %eax");
 __asm("movl DWORD %PTR[t2 + 4], %edx");


 delta_t = t2 - t1;
 cout << delta_t;
 }



После попытки компиляции которого я был обруган:
junk '[t1]' after expression
junk '[t1+4]' after expression
junk '[t2]' after expression
junk '[t2+4]' after expression


Метод усиленного вглядывания в текст ни к чему ни привел.


Не могли бы вы поглядеть коллективным разумом и тыкнуть меня носом?


M Дубль текста удален
A Дубль текста удален

Ассемблерные вставки в Си++

Добавлено: 18 янв 2014, 22:10
zykov
Наверно нужно уточнить, что за компилятор...
('__asm' и тем более его аргумент точно не входит стандарт C++.)

А насчёт измерений, как насчёт прерываний?

Ассемблерные вставки в Си++

Добавлено: 18 янв 2014, 22:16
Wild Bill
zykov писал(а):Source of the post
Наверно нужно уточнить, что за компилятор...
('__asm' и тем более его аргумент точно не входит стандарт C++.)

А насчёт измерений, как насчёт прерываний?
Я бы сказал обиднее... Есть стандартная процедура для определения долей секунды для операции... Кто хочет изобретать велосипед --- кирку им в руки!

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 10:12
NT
zykov писал(а):Source of the post А насчёт измерений, как насчёт прерываний?

Я согласен с Андреем.
Зачем такие заморочки?
Вчера весь вечер анализовал код ТС и ничего не понял.
Уж лучше вызов низкоуровних функций (неявно их выполнение идет через прерывания).

Как например тут:

Код: Выбрать все

 // Test.cpp - program
#include <iostream>
#include <windows.h>
#include <intrin.h>
#include <stdint.h>
using namespace std;

uint64_t rdtsc()
{
    return __rdtsc();
}

int main()
{
    cout << rdtsc() << "\n";    cin.get();    return 0;}

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 10:23
kiv
Ну, надо смотреть правила конкретного компилятора. Visual C++ вполне компилирует

Код: Выбрать все

 __asm CPUID; // "out-of-order"
 __asm RDTSC;

 __asm mov DWORD PTR[t1], eax;
 __asm mov DWORD PTR[t1 + 4], edx;


Я, честно говоря, предпочитаю под Windows QueryPerformanceFrequency/QueryPerformanceCounter.

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 11:32
NT
kiv писал(а):Source of the post Ну, надо смотреть правила конкретного ...
Скопилировать под Windows for "Dev-C++ compiler"
в нотации Intela (без movl), проходит вот так например:

Код: Выбрать все

 //Test4.cpp program
#include <iostream>
using namespace std;

long long t1=0,t2=0;
static long long delta_t=0;

int main(){
    
    __asm("CPUID"); //  "out-of-order"
    __asm("RDTSC");
    __asm("mov DWORD PTR[_t1], eax");
    __asm("mov DWORD PTR[_t1 + 4], edx");

    //????? ??????????? ???, ????? ?????????? ???????? ? ??????????

     __asm("CPUID");
     __asm("RDTSC");
     __asm("mov DWORD PTR[_t2], eax");
     __asm("mov DWORD PTR[_t2 + 4], edx");

    delta_t = t2 - t1;
    cout << delta_t;    return 0;}

Но что делает программа - ума не приложу.
Т.е. теоретический знаю, что должна.
Но так, как написана - не врублюсь.

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 12:57
kiv
NT писал(а):Source of the post
Скопилировать под Windows for "Dev-C++ compiler"

Не хочется начинать еще один спор, но "Dev-C++ — свободная интегрированная среда разработки приложений для языков программирования C/C++.", как сказано в Википедии... То, что в основном используется с компилятором MinGW, еще ни о чем не говорит

А по сути - да, нотация была явно GNU-шная, но тут я, увы, не помощник...

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 13:22
NT
Kiv, да я и не спорю.
Просто дома у меня был только этот простой компилятор (для моих тестовых целей вполне достаточный).
Я на нём и пытался скомпилировать и проанализировать результат.



PS.
kiv писал(а):Source of the post ... в основном используется с компилятором MinGW ...
Совершенно верно в Dev-C++ у меня в опциях до выбора MinGW-32 или MinGW-64.

Ассемблерные вставки в Си++

Добавлено: 19 янв 2014, 18:13
folk
В таком виде вроде работает но сразу скажу что количество плавает изрядно - не вижу большого смысла в таком измерении
Лучше все же повторить 10^5 раз и поделить время на 10^5)

Код: Выбрать все

#include <iostream>
#include <stdio.h>
using namespace std;

#include <stdint.h>
inline unsigned long long rdtsc() {
 register unsigned int lo, hi;
 asm volatile (
 "cpuid \n"
 "rdtsc"
 : "=a"(lo), "=d"(hi) /* outputs */
 : "a"(0) /* inputs */
 : "%ebx", "%ecx"); /* clobbers*/
 return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
}


int main()
 {
 register long long t1=0,t2=0;
 register long long delta_t=0;

 __asm("CPUID"); // "out-of-order"
 t1 = rdtsc();

__asm ("nop");
 //Здесь выполняется код, время исполнения которого и замеряется

 t2 = rdtsc();

 delta_t = t2 - t1;
 printf("%ld=\n",delta_t);
 }