Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Скорость работы драйвера  (Прочитано 18473 раз)
0 Пользователей и 1 Гость смотрят эту тему.
MikePol
Постоялец

ru
Offline Offline

« : 03-06-2004 09:07 » 

Здраствуйте .
Написал драйвер, точнее немного переделал чужой .
По IO_CTL считываю слово из порта ввода - вывода .
В тестовой программе вызываю DeviceIoControl 100 000 раз и присваиваю возвращаемое значение переменной. Измерил время :
 4,200 с за 100 000.  Молчу
Даже Windriver делает это за  0,660 с ....  
Что делать ?
Записан
maaaaaad
Гость
« Ответ #1 : 03-06-2004 09:41 » 

измерить снова. =) Посмотри чтобы размер выходных данных был 4 а входных - 0 (в DeviceIoControl). Желательно в драйвере выстави (!) буферизацию DO_BUFFERING_IO (кажется так).
Записан
maaaaaad
Гость
« Ответ #2 : 03-06-2004 09:47 » 

Есть диспечеры FastIo, я четсно никогда ими не пользовался. Думаю что видрайвер использует тот же ioctl, и скорость работы не может быть больше в принципе.
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #3 : 03-06-2004 09:50 » 

Это оказалась Debug версия ...   но после того как она стала Release
время сократилось, но до 0.800 с .  Все равно медленнее чем WinDriver+Delphi
А зачем размер входных данных 4 ? Я же слово получаю ?
И где буферизацию выставить ? В DriverEntry ?
Записан
maaaaaad
Гость
« Ответ #4 : 03-06-2004 09:52 » 

я опечатался - для слов размер выходных данных - 2
Записан
maaaaaad
Гость
« Ответ #5 : 03-06-2004 09:53 » 

посмотри описание #define IO_CTL и кинь его сюда
Записан
maaaaaad
Гость
« Ответ #6 : 03-06-2004 09:54 » 

и кинь обработку после

case IO_CTL:
Записан
maaaaaad
Гость
« Ответ #7 : 03-06-2004 09:56 » 

нет, буферизация в Entry выставляется для IRP_MJ_READ IRP_MJ_WRITE
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #8 : 03-06-2004 10:05 » 

case IOCTL_SEND_WORD_TO_USER:
   {  
      DO_BUFFERING_IO
      ULONG InputL= IrpStack->Parameters.DeviceIoControl.InputBufferLength;
      ULONG OutputL= IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
      USHORT *buff;

        if(method==METHOD_BUFFERED)
      {
         buff = (PUSHORT)Irp->AssociatedIrp.SystemBuffer;
      }
      else
         if (method==METHOD_NEITHER)
         {
            buff=(PUSHORT)Irp->UserBuffer;
         }
         else
         {
            status = STATUS_INVALID_DEVICE_REQUEST;
            break;
         }
   
        USHORT addr_=0x390;
        *buff=READ_PORT_USHORT((PUSHORT)addr_);
      *buff=*buff-1;
      /*   unsigned char a=111;
 
      //a=READ_PORT_USHORT(adr);  */
         
      BytesTxd=2;
      break;
   }

///////////////////////////////////////////////////////////////////

#define IOCTL_SEND_WORD_TO_USER CTL_CODE( \
   FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
Записан
maaaaaad
Гость
« Ответ #9 : 03-06-2004 10:06 » 

проверь описание

#define IO_CTL CTL_CODE(FILE_DEVICE_FOREVIEW, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS

метод должен быть METHOD_BUFFERED с небольшими данными он, я думаю быстрее
Записан
maaaaaad
Гость
« Ответ #10 : 03-06-2004 10:13 » 

case IOCTL_SEND_WORD_TO_USER:
{
USHORT *buff;
USHORT addr_=0x390;
buff = (PUSHORT)Irp->AssociatedIrp.SystemBuffer;
 
*buff=READ_PORT_USHORT((PUSHORT)addr_);
//*buff=*buff-1;
break;

так еще посмотри куда попадаем после брейка.
посмотри что бы было
Irp->IoStatus.Information = 0;
Записан
maaaaaad
Гость
« Ответ #11 : 03-06-2004 10:15 » 

*buff=*buff-1;

вин драйвер, наверное такое не делает! =)
Записан
maaaaaad
Гость
« Ответ #12 : 03-06-2004 10:16 » 

тьфу Irp->IoStatus.Information = 2
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #13 : 03-06-2004 10:31 » 

после break вызывается
 CompleteIrp(Irp,status,BytesTxd);
                                          2

NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info)
{
   Irp->IoStatus.Status = status;
   Irp->IoStatus.Information = info;
   IoCompleteRequest(Irp,IO_NO_INCREMENT);
return status;


}
Записан
maaaaaad
Гость
« Ответ #14 : 03-06-2004 10:37 » 

вынеси перед брейком

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 2;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;

видишь, выполняется дофига лишних операций. в виндрайвер этого нет. это сделано профи для лохов. Еще придется немного опримизировать если дело уж пошло о скорости (в самом диспечере перед switch аналогично много shit)

Если только и нужно, что всего читать портик, а опыта написания драйверов особого то и нет, то, наверно виндрайвер будет лучше.
Записан
maaaaaad
Гость
« Ответ #15 : 03-06-2004 10:38 » 

Oh god, Sadam's got his own Laden/ wit'
his own private plane, his own pilot,
set to blow college dorm rooms doors
off the hinges/oranges, peach, pears,
 plums syringes.
Vnnnn vnnnn, yeah here I come,
I'm inches/ away from you,
 dear fear none,
hip hop is in a state of nine-one-one so...

Lets get down to business.
I don't got no time to play around what
is this/Must be a circus in town,
lets shut the shit down on these clowns.
Can I get a witness? HELL YEAH!
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #16 : 03-06-2004 10:46 » 

Да нет ..  не только портик. Это просто начало. Мне показалось легче всего портик считать. Потом придется прерывания обрабатывать и т.д (к PCI будет)
Виндрайвер требует постоянного обновления версий и устанавливается иногда криво.
Лучше один раз изучить...  Надо сделать быстрее  Жжешь
Я через виндрайвер время измерял, так он через dll работал, так что думаю должно быстрее получиться
Записан
maaaaaad
Гость
« Ответ #17 : 03-06-2004 10:50 » 

Цитата

так он через dll работал


в длл вынесен только интерфейс для виндрайвер драйвера. этот интерфейс, повторяю работает через тот же ioctl. поищи что то типа *win*.sys, у меня никогда не было виндрайвера, но думаю он тазывается так
Записан
maaaaaad
Гость
« Ответ #18 : 03-06-2004 10:52 » 

на разовых операциях чтения порта в ед. числе убыстрения не стоит ожидать.
а вот с прерываваниями дела в виндрайвере точно хуже =)))))
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #19 : 03-06-2004 10:52 » 

Да я понимаю что интерфейс ...  но все равно же  медленнее через dll
чем напрямую ....
Записан
maaaaaad
Гость
« Ответ #20 : 03-06-2004 10:53 » 

посему рекламу ddk считаю закрытой =)
Записан
MikePol
Постоялец

ru
Offline Offline

« Ответ #21 : 03-06-2004 10:53 » 

Может Нумегой воспользоваться ? Вообще стоит она того или нет ?
Записан
AlexANDor
Гость
« Ответ #22 : 03-06-2004 11:31 » 

MikePol, раз уж пошла такая суровая оптимизация - все ж попробуй _inpw вместо READ_PORT_USHORT (инлайн-подстановка вместо импорта из hal.dll).
Записан
maaaaaad
Гость
« Ответ #23 : 03-06-2004 11:45 » 

FastIoDispatch example
X-NEWS: cmkrnl comp.os.ms-windows.programmer.nt.kernel-mode: 6795
Relay-Version: ANU News - V6.1B10 10/08/94 OpenVMS VAX V5.5-2; site cmkrnl
Path: cmkrnl!newsfeed.cts.com!newshub.cts.com!news.aloha.net!
 svr1.gstis.net!news-chi-8.sprintlink.net!
 news-pull.sprintlink.net!news.sprintlink.net!
 news-peer.sprintlink.net!howland.erols.net!
 newsfeed.internetmci.com!eanews1!trsvr!news
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
Subject: FastIoDispatch, example code
Message-ID: <01bc23ed$36cc47f0$d0e43fc0@djm8>
From: "Duane J. McCrory"
Date: Wed, 26 Feb 1997 13:48:28 GMT
Sender: news@tr.unisys.com (cnews news id.)
Organization: Unisys Corporation
X-Nntp-Posting-Host: djm8.tr.unisys.com
X-Newsreader: Microsoft Internet News 4.70.1155
Lines: 93

I got a request for sample FastIoDispatch code. Here's an example for Ioctls.
static FAST_IO_DISPATCH fast_io_dispatch;

static NTSTATUS driver_dispatch_device_control(IN DEVICE_OBJECT *
  dev, IN
IRP *irp) {
    PIO_STACK_LOCATION irp_stk;
    NTSTATUS status;

    // in my case, I never need an IRP for a device_control opera
    // tion
    // so if my IRP_MJ_DEVICE_CONTROL function happens to get cal
    // led
    // I can make use of the fast procedure that I've implemented

    irp_stk = IoGetCurrentIrpStackLocation(irp);

    driver_dispatch_device_control_fast(irp_stk->FileObject, TRUE
     ,
        irp_stk->Parameters.DeviceIoControl.Type3InputBuffer,
        irp_stk->Parameters.DeviceIoControl.InputBufferLength,
        irp->UserBuffer,
        irp_stk->Parameters.DeviceIoControl.OutputBufferLength,
        irp_stk->Parameters.DeviceIoControl.IoControlCode,
        &irp->IoStatus, dev);
    status = irp->IoStatus.Status;
    IoCompleteRequest(irp, IO_NO_INCREMENT);
    return status;
}

static BOOLEAN driver_dispatch_device_control_fast(IN FILE_OBJECT
*FileObject,
        IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG
InputBufferLength,
        OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLen
         gth,
        IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus, IN
DEVICE_OBJECT *dev) {

    // setup default result
    IoStatus->Status = STATUS_SUCCESS;
    IoStatus->Information = 0;

    switch (IoControlCode) {
    case IOCTL_OUTPUT_TO_APPLICATION:
        // this is an example for sending data to an application
        if (OutputBufferLength >= sizeof(YOUR_OUTPUT_AREA)) {
         __try {
         *(YOUR_OUTPUT_AREA *)OutputBuffer =          d>
         IoStatus->Information = sizeof(YOUR_OUTPUT_AREA);
         } __except(EXCEPTION_EXECUTE_HANDLER) {
         IoStatus->Status = GetExceptionCode();
         }
        } else
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        return TRUE;
    default:
        // Set default return information
        IoStatus->Status = STATUS_NOT_IMPLEMENTED;
        return TRUE;
    }
    // note that you would return FALSE if you want the standard
IRP_MJ_DEVICE_CONTROL
    // dispatch routine called, in my case I always return TRUE
}

NTSTATUS PROCEDURE DriverEntry(IN DRIVER_OBJECT *drv, IN PUNICODE
  _STRING
RegistryPath) {
    .
    .
    .
    RtlZeroMemory(&fast_io_dispatch, sizeof(fast_io_dispatch));
    fast_io_dispatch.SizeOfFastIoDispatch = sizeof(fast_io_dispat
     ch);
    fast_io_dispatch.FastIoDeviceControl =
driver_dispatch_device_control_fast;
    drv->FastIoDispatch = &fast_io_dispatch;
    drv->MajorFunction[IRP_MJ_CREATE] = driver_dispatch;
    drv->MajorFunction[IRP_MJ_CLOSE] = driver_dispatch;
    drv->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
driver_dispatch_device_control;
    drv->MajorFunction[IRP_MJ_READ] = driver_dispatch;
    drv->MajorFunction[IRP_MJ_WRITE] = driver_dispatch;
    drv->MajorFunction[IRP_MJ_CLEANUP] = driver_dispatch;
    drv->MajorFunction[IRP_MJ_SHUTDOWN] = driver_dispatch;

    drv->DriverUnload = driver_unload;
    .
    .
    .
}
--
Duane.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines