Перейти к содержанию
    

Глюки оптимизации

по моим криптографическим тестам (ЭЦП и поточное шифрование).

 

если не секрет то за какое время выполняется подпись ключом 2048bit? У меня F207 и на либах из PolarSSL получилось 2.7с без оптимизации и 1.5 с полной оптимизацией (IAR). Но при полной оптимизации дохнет драйвер ethernet от ST :-)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но при полной оптимизации дохнет драйвер ethernet от ST :-)

Можно, конечно, снижать оптимизацию выборочно. Но по-хорошему такой драйвер надо оторвать и выбросить.

Кстати, когда я ваял свой драйвер ethernet для STM32 (uIP), то подивился, насколько просто это оказалось. Всего 200 строчек:

/**
* @file  stm32eth.h
* @brief Драйвер Ethernet для STM32
*/

#include "stm32eth.h"
#include "stm32f2regs.h"
#include "timer.h"
#include "net/uip.h"
#include <string.h>

#define SMI_TMPL 0x00000004 /* sets SMI clock range and PHY address */
#define RX_BUF_SIZE     256
#define RX_RING_SIZE    32

static bool link, act;
/* the only TX descriptor used in this program */
static uint32_t volatile tx_desc[4] = { 0, 0, (uint32_t)uip_buf, 0 };
static uint32_t volatile rx_desc[RX_RING_SIZE][4];
static uint8_t volatile rx_buf[RX_RING_SIZE][RX_BUF_SIZE];
/* first descriptor in frame, next descriptor to check */
static unsigned int rx_first, rx_cur;

static bool
smi_busy(void)
{
       return (ETH_MACMIIAR & 1) != 0;
}

static void
smi_write(int reg, int val)
{
       ETH_MACMIIDR = val;
       ETH_MACMIIAR = (reg << 6) | SMI_TMPL | 3;
       while (smi_busy())
       {
               /* wait */
       }
}

static void
smi_start_read(int reg)
{
       ETH_MACMIIAR = (reg << 6) | SMI_TMPL | 1;
}

static int
smi_read_data(void)
{
       return ETH_MACMIIDR;
}

static void
phy_init(void)
{
       smi_write(0, 0x1100);
       smi_write(4, 0x0021);/* auto-negotiate 10Mb half-duplex only */
}

static void
fill_rx_desc(void)
{
       int i;
       for (i = 0; i < RX_RING_SIZE; i++)
       {
               rx_desc[i][0] = (1u << 31); /* OWN bit */
               rx_desc[i][1] = RX_BUF_SIZE;
               rx_desc[i][2] = (uint32_t)&rx_buf[i];
       }
       rx_desc[RX_RING_SIZE - 1][1] |= (1 << 15); /* end of ring */
}

void
stm32eth_init(void)
{
       /* enable clocking of MAC core, ports A, B, C */
       RCC_AHB1ENR |= 0x1E000007;
       fill_rx_desc();
       GPIOA_AFRL |= 0xB000BBBB;
       GPIOB_AFRL |= 0x000000BB;
       GPIOB_AFRH |= 0x00BBBB0B;
       GPIOC_AFRL |= 0x00BBBBB0;
       GPIOA_MODER |= 0x000080AA;
       GPIOB_MODER |= 0x0AA2000A;
       GPIOC_MODER |= 0x00000AA8;
       timer_delay(TIMER_TPS / 1000);
       ETH_DMATDLAR = (uint32_t)&tx_desc;
       ETH_DMARDLAR = (uint32_t)&rx_desc;
       ETH_MACCR = (1 << 16) /* disable carrier sense */
                 | (1 <<  3) /* enable transmitter */
                 | (1 <<  2);/* enable receiver */
       ETH_DMAOMR = (1 << 21) /* transmit store and forward */
                  | (1 << 13) /* start transmission */
                  | (1 <<  1);/* start reception */
       phy_init();
       smi_start_read(1);
}

void
stm32eth_setmac(const uint8_t mac[6])
{
       ETH_MACA0LR = *(uint32_t*)mac;
       ETH_MACA0HR = *(uint16_t*)(mac + 4);
}

static void
collect_frame(void)
{
       int i, remlen;
       uint8_t *dst = uip_buf;
       remlen = (rx_desc[rx_cur & (RX_RING_SIZE - 1)][0] & 0x3FFF0000) >> 16;
       uip_len = remlen;
       for (i = rx_first; i <= rx_cur; i++)
       {
               int len;
               len = (i != rx_cur) ? RX_BUF_SIZE : remlen;
               memcpy(dst, (void*)rx_buf[i & (RX_RING_SIZE - 1)], len);
               dst += len;
               remlen -= len;
       }
}

static void
reinit_rx_desc(void)
{
       unsigned int i;
       for (i = rx_cur; i != (rx_first - 1); i--)
       {
               rx_desc[i & (RX_RING_SIZE - 1)][0] = 1u << 31; /* OWN bit */
       }
}

static void
rx_poll(void)
{
       uint32_t status;
       status = rx_desc[rx_cur & (RX_RING_SIZE - 1)][0];
       if (status & (1u << 31)) /* OWN bit */
       {
               return;
       }
       if (status & (1 << 9)) /* first segment */
       {
               rx_first = rx_cur;
       }
       if (status & (1 << 8)) /* last segment */
       {
               if ((status & 0x4000F89F) == 0) /* error bits */
               {
                       collect_frame();
               }
               reinit_rx_desc();
       }
       rx_cur++;
}

void
stm32eth_poll(void)
{
       static timer_value prev;
       timer_value now;
       now = timer_getval();
       if (timer_ticksbetween(prev, now) > TIMER_TPS / 100)
       {
               link = !!(smi_read_data() & 4);
               smi_start_read(1);
               prev = now;
       }
       rx_poll();
}

void
stm32eth_send(void)
{
       tx_desc[1] = uip_len;
       tx_desc[0] = (1u << 31) /* OWN bit */
                  | (1  << 29) /* last segment */
                  | (1  << 28) /* first segment */
                  | (1  << 21);/* end of ring */
       ETH_DMATPDR = 0; /* start transmission */
       while (tx_desc[0] & (1u << 31))
       {
               /* wait until TX descriptor is released */
       }
}

bool
stm32eth_link(void)
{
       return link;
}

bool
stm32eth_act(void)
{
       bool ret;
       ret = act;
       act = false;
       return ret;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если не секрет то за какое время выполняется подпись ключом 2048bit?

Я пока до RSA не добрался. Есть "советский" 34.310/34.311, украинский 4145-2002, и беларусский 1176.2.

34.310 и 1176.2 тоже на модульной арифметике основаны, поэтому результаты подобные RSA будут - то же самое модульное возведение в степень.

1176.2 при длине 2462 бита дает 680мс на выработку подписи.

 

У меня F207 и на либах из PolarSSL получилось 2.7с без оптимизации и 1.5 с полной оптимизацией (IAR). Но при полной оптимизации дохнет драйвер ethernet от ST :-)

IAR начиная с 6.2x глючит при оптимизации, никак они не исправят, откатитесь на 5.x.

PolarSSL - хорошо и аккуратно написан и структурирован код. Но с точки зрения ресурсов/скорости - имхо, скорее середнячок.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IAR начиная с 6.2x глючит при оптимизации, никак они не исправят, откатитесь на 5.x.

PolarSSL - хорошо и аккуратно написан и структурирован код. Но с точки зрения ресурсов/скорости - имхо, скорее середнячок.

Не замечал. У меня с Cortex-M3 всё ок. В чём именно глюк?

Если что-то не работает при оптимизации - в первую очередь надо обратить внимание на свой код и в последнюю - на компилятор. имхо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не замечал. У меня с Cortex-M3 всё ок. В чём именно глюк?

Если что-то не работает при оптимизации - в первую очередь надо обратить внимание на свой код и в последнюю - на компилятор. имхо

Угу - в этой теме проблема описана

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так что, если без оптимизации всё работает, а с ней -- нет, то дело в оптимизаторе, а не исходном коде.
Ага, конечно. Поищите по форуму ключевое слово volatile и темы про задержки на пустых циклах.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, конечно. Поищите по форуму ключевое слово volatile и темы про задержки на пустых циклах.

+1

у IAR оптимизатор очень любит циклы выкидывать, обращения к данным...

так что в циклы надо __no_operation вставлять, а у данных volatile

 

Ошибки в оптимизаторе появляются, но обычно все таки проблема именно в коде и в том что многие привыкли к тому что другие компиляторы сами "додумывают" где volatile и пустые циклы не убирают...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Корректный оптимизатор ни при каких условиях не должен давать неработоспособный код.

Это просто неверное утверждение. Если в исходниках накосячено, то в зависимости от настроек компилятора, дня недели и погоды за окном код может генериться как рабочий, так и нерабочий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а можно ли где-то найти что-то подобие release notes / mail list со списком исправленных или известных багов?

release notes начиная с 5.40 такой информации, судя по всему, не содержат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а можно ли где-то найти что-то подобие release notes / mail list со списком исправленных или известных багов?

release notes начиная с 5.40 такой информации, судя по всему, не содержат.

Смотрите в Release notes for individual components.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...