Jump to content

    
Sign in to follow this  
Sagittarius

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

Recommended Posts

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

 

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

 

Share this post


Link to post
Share on other sites
Но при полной оптимизации дохнет драйвер 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;
}

Share this post


Link to post
Share on other sites
если не секрет то за какое время выполняется подпись ключом 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 - хорошо и аккуратно написан и структурирован код. Но с точки зрения ресурсов/скорости - имхо, скорее середнячок.

 

Share this post


Link to post
Share on other sites
IAR начиная с 6.2x глючит при оптимизации, никак они не исправят, откатитесь на 5.x.

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

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

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

Share this post


Link to post
Share on other sites
Не замечал. У меня с Cortex-M3 всё ок. В чём именно глюк?

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

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

 

Share this post


Link to post
Share on other sites

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

Share this post


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

 

Share this post


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

+1

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

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

 

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

Share this post


Link to post
Share on other sites
Корректный оптимизатор ни при каких условиях не должен давать неработоспособный код.

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

Share this post


Link to post
Share on other sites

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

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

Share this post


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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this