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

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

ua
Offline Offline

« : 15-04-2012 16:09 » 

Доброе Время суток!!!
 Столкнулся с проблемой в скорости передачи данных через WDM драйвер, скорость очень низкая по сравнению с драйвером написанном в nuMega. Привожу код функций передачи данных:
Код:
#define MDMAI_MEM_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_OUT_DIRECT , FILE_ANY_ACCESS)
#define MDMAI_MEM_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_IN_DIRECT , FILE_ANY_ACCESS)
тело функции:
Код:
PMDMAI_DEVICE_EXTENSION pdx = (PMDMAI_DEVICE_EXTENSION) fdo->DeviceExtension;
 
    NTSTATUS status = STATUS_SUCCESS;
                    DbgPrint("enter in DeviceControl!\n");
    ULONG info = 0;
 
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
    ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
    ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
    ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
//...
case  MDMAI_MEM_READ://IOCTL_READ_IMAGE:
        {
            DbgPrint("enter MDMAI_MEM_READ:\n");
 
                    if (cbin < sizeof(XDSP_READ_WRITE_MEMORY_ARGS*))
                     {
                        status = STATUS_INVALID_PARAMETER;
                        break;
                     }
 
                    XDSP_READ_WRITE_MEMORY_ARGS* p = (XDSP_READ_WRITE_MEMORY_ARGS*)Irp->AssociatedIrp.SystemBuffer;
                            KdPrint((DRIVERNAME " — Size of XDSP_READ_WRITE_MEMORY_ARGS = %I32x \n", sizeof(XDSP_READ_WRITE_MEMORY_ARGS)));
 
                    if (p!=NULL)
                    {
                        ULONG offset = p->ByteOffset;                       
                            KdPrint((DRIVERNAME " — Device on real addrr %I32x, offset = %I32x \n",pdx->MemBar1, offset));
                        p->DwordCount = READ_REGISTER_ULONG((PULONG)(pdx->MemBar1+offset));
                            KdPrint((DRIVERNAME " - Device on addrr %I32x has 0x%I32x   \n", pdx->MemBar1+offset, p->DwordCount));
 
                        info = sizeof(p->DwordCount);
                            KdPrint((DRIVERNAME " — Size of DATA = %d \n", info));
 
                        PVOID pInputBuffer  = Irp->AssociatedIrp.SystemBuffer;
                        PVOID pOutputBuffer = NULL;
 
                            if(Irp->MdlAddress)
                                {
                                    pOutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
                                }
 
                            if(pInputBuffer && pOutputBuffer)
                                {                                   
                                        DbgPrint("%i >= %i", cbout, info);
                                    if(cbout >= info)
                                    {
                                        RtlCopyMemory(pOutputBuffer, &p->DwordCount, info);
                                          status = STATUS_SUCCESS;
                                    }else status = STATUS_BUFFER_TOO_SMALL;
                                }
 
                    }else status = STATUS_INVALID_PARAMETER;
 
            break;
        }
 
case MDMAI_MEM_WRITE://IOCTL_WRITE_IMAGE:
        {
                    DbgPrint("enter MDMAI_MEM_WRITE:\n");                               
 
                    if (cbin < sizeof(XDSP_READ_WRITE_MEMORY_ARGS*))
                     {
                        status = STATUS_INVALID_PARAMETER;
                        break;
                     }
 
                    XDSP_READ_WRITE_MEMORY_ARGS* p = (XDSP_READ_WRITE_MEMORY_ARGS*)Irp->AssociatedIrp.SystemBuffer;
                        KdPrint((DRIVERNAME " — Size of XDSP_READ_WRITE_MEMORY_ARGS = %d \n", sizeof(XDSP_READ_WRITE_MEMORY_ARGS)));
 
                    if (p!=NULL)
                    {
                        ULONG offset = p->ByteOffset;                       
                            KdPrint((DRIVERNAME " — Device on real addrr %I32x, offset = %I32x \n",pdx->MemBar1, offset));                     
                            KdPrint((DRIVERNAME " - Device on addrr %I32x has 0x%I32x   \n",pdx->MemBar1+offset, p->DwordCount));
                        WRITE_REGISTER_ULONG((PULONG)(pdx->MemBar1+offset), p->DwordCount);
                        info = sizeof(p->DwordCount);
                            KdPrint((DRIVERNAME " — Size of DATA = %d \n", info));
                        ULONG Data = READ_REGISTER_ULONG((PULONG)(pdx->MemBar1+offset));
                            KdPrint((DRIVERNAME " — Read DATA = %I32x \n", Data));
                          status = STATUS_SUCCESS;
                    }else status = STATUS_INVALID_PARAMETER;
 
            break;
        }
Что может быть?
 Спасибо!!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 15-04-2012 21:40 » 

Цитата
скорость очень низкая по сравнению с драйвером написанном в nuMega
не совсем понятно: насколько низкая?
чем приведенный код отличается от кода нумеги?
с какими параметрами оно запускается?
как изменяется производительность?
сборка драйвера релиз/дебаг?
MDMAI_MEM_WRITE/MDMAI_MEM_READ  -что вообще делает? суть не понял.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sabbatazh
Помогающий

ua
Offline Offline

« Ответ #2 : 16-04-2012 09:55 » 

Ochkarik, nuMega использует свои классы для общения приложения с устройством... я же переписываю на DDK... и скорость чтения записи отличается почти в 5 раз... приложение пользователя не переписывалось...
эти функции общаются с регистрами PCI READ_REGISTER_ULONG(), WRITE_REGISTER_ULONG()...
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 16-04-2012 11:09 » 

все равно непонятно: что за классы, в каком месте падение производительности, при каких условиях, как изменялось падение производительности, как полностью выглядит производительная функция и не-производительная.
по представленному вами куску кода - ничего сказать нельзя.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sabbatazh
Помогающий

ua
Offline Offline

« Ответ #4 : 16-04-2012 11:20 » 

я сам запутался!)))) могу привести код из nuMega... просто код сгенерируемый студией мне не о чем не говорит описания на него толком нет у меня...
порылся в сети и нашел такую штуку: пишут, что эффективнее использовать WRITE_REGISTER_BUFFER_ULONG и READ_REGISTER_BUFFER_ULONG чем  RtlCopyMemory
Как Вы считаете, это так???
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 16-04-2012 11:52 » 

ну так попробуйте) я вообще memcpy использовал. но рекомендую в качестве аргумента длинны блока указывать в явном виде так: "buff_len_dw<<2". в этом случае memcpy мне разворачивало в rep movsd, без дополнительной проверки на отдельные байты. плюс выравнивание конечно 8 байт должно стоять.

ps а о каких величинах производительности идет речь? гигабайты/сек?
« Последнее редактирование: 16-04-2012 11:53 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sabbatazh
Помогающий

ua
Offline Offline

« Ответ #6 : 16-04-2012 12:03 » 

Цитата
ps а о каких величинах производительности идет речь? гигабайты/сек?
Почти!)))
Спасибо, за подсказку, буду пробовать!
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 16-04-2012 13:56 » 

да, а еще лучше выравнивание вообще на кэш линейку сделать. или вообще на 4к)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
sabbatazh
Помогающий

ua
Offline Offline

« Ответ #8 : 25-04-2012 16:22 » new

Спасибо!!!
Воспользовался WRITE_REGISTER_BUFFER_ULONG и READ_REGISTER_BUFFER_ULONG без выделения буфера - "передача на лету" и прирост в скорости вырос на 30% по сравнению даже с оригиналом...
тему можно закрывать!!!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines