Цитата(Genadi Zawidowski @ Sep 6 2016, 12:54)

win64 - проект собрался, работает нормально. измерениями ускорения/замедляния оптимизации вычислений не занимался. 580184 байт кода против 572812 намекают, что должно стать шустрее.
по поводу C++14, проверил - мое работает.
накидал примерчик
проверяем работу стд вектора и некоторые фичи с++11/14
CODE
#include "console.h"
#include "engine.h"
#include "rt_counter.h"
#include "vdt/vdtMath.h"
#include <vector>
TEngineTask* EngineTask ;
typedef struct
{
float real ;
float image ;
} signal_t ;
typedef std::vector<signal_t,KgpAllocator<signal_t>> signal_vec_t ;
void TEngineTask::Code()
{
TickType_t xLastWakeTime = TTaskUtilities::GetTickCount();
signal_vec_t signal_vec ;
signal_vec.resize( 32 ) ;
// range-base циклы
for(auto &element: signal_vec)
{
element = {0 , -1} ;
}
// энумерация по итераторам, вычисление индекса элемента и присваивание
for( auto it = signal_vec.begin() ; it != signal_vec.end() ; it++ )
{
auto pos = std::distance(signal_vec.begin(),it);
signal_t tmp ;
vdt::fast_sincosf( vdt::details::VDT_PI_F * pos / 32 , tmp.real , tmp.image) ;
*it = tmp ;
}
while(1)
{
if( !active )
Suspend();
DelayUntil( &xLastWakeTime, 1000 ) ;
for(auto &element: signal_vec)
{
rmsg("{%3.3 %1.3}\n", element.real , element.image );
}
}
}
вывод в консольку:
CODE
{000.000 1.000}
{000.098 0.995}
{000.195 0.980}
{000.290 0.956}
{000.382 0.923}
{000.471 0.881}
{000.555 0.831}
{000.634 0.773}
{000.707 0.707}
{000.773 0.634}
{000.831 0.555}
{000.881 0.471}
{000.923 0.382}
{000.956 0.290}
{000.980 0.195}
{000.995 0.098}
{001.000 -0.000}
{000.995 -0.098}
{000.980 -0.195}
{000.956 -0.290}
{000.923 -0.382}
{000.881 -0.471}
{000.831 -0.555}
{000.773 -0.634}
{000.707 -0.707}
{000.634 -0.773}
{000.555 -0.831}
{000.471 -0.881}
{000.382 -0.923}
{000.290 -0.956}
{000.195 -0.980}
{000.098 -0.995}
нужно сделать важный коментарий - если посмотреть повнимательней в мой код то Вы заметите что стандартный аллокатор по умолчанию я не использую - это злое зло для машин с терабайтами озу и терагерцами в процессорах. у меня свой легковесный аллокатор который я подсовываю STL, далее нужно сказать что это аллокатор НЕ использует стандартный new/delete - а использует мои враgеры lдля этих С++ операторов которые НЕ используют стандартные malloc/free - а используют мою обертку вокруг TLSF
все эти танцы с бубном необходимы для обхода слежующих двух граблей
1. new и delete c танадартной реализации могут генерить эксепшены которыя мы выпиливаем - в микроэмбедет оно плохо ложится, поэтому свой врапер на эти операторы
2. malloc и free которые нужны для new и delete из newlib лично у меня вызывают печаль поэтому я их отправил к TLSF который линкуется во все мои проекты.
но Вы не обязаны использовать ни враперы по типу моих ни вообще stdlibc для использования чистого C++14, но без STL теряется изящность - там много написано и писать заново свое корявое не интересно. тем немение использую контейнеры прийдется реализовать работу с памятью о чем выше сообщено.
все эти мысои оформлены в виде нескольких мален7ьких хидеров - вот их реализация:
supc++.h
CODE
#ifndef __SUPC++_H__
#define __SUPC++_H__
// KGP tools embedded SDK
// Chernov S.A. aka klen
// klen_s@mail.ru
#include <stddef.h> // define size_t
#include <bits/c++config.h> // nedded for _GLIBCXX_NOEXCEPT macro and c++ exception handler redefinition
extern "C" void *malloc( size_t WantedSize );
extern "C" void free( void* pv );
// see referense of 'noexcept' in $TARGET/lib/gcc/$TARGET/X.X.X/include/c++/$TARGET/bits/c++config.h
// _GLIBCXX_NOEXCEPT is macro wrap of noexcept
//------------------------------------------------------------------
// определение функции оператор new
inline void* operator new(size_t size) _GLIBCXX_NOEXCEPT
{
return malloc( size );
}
//------------------------------------------------------------------
// определение функции оператор delete
inline void operator delete(void* ptr) _GLIBCXX_NOEXCEPT
{
free(ptr);
}
inline void operator delete(void* ptr , size_t size) _GLIBCXX_NOEXCEPT
{
free(ptr);
}
//------------------------------------------------------------------
// определение функции оператор new[]
inline void* operator new[] (size_t size) _GLIBCXX_NOEXCEPT
{
return malloc( size );
}
//------------------------------------------------------------------
// определение функции оператор delete[]
inline void operator delete[] (void* ptr) _GLIBCXX_NOEXCEPT
{
free(ptr);
}
inline void operator delete[] (void* ptr, size_t size) _GLIBCXX_NOEXCEPT
{
free(ptr);
}
//------------------------------------------------------------------
// default throw catchers
__attribute__((__noreturn__)) inline void throw_exeption_catcher()
{
while(1)
asm volatile("nop");
}
__attribute__((__noreturn__)) inline void throw_exeption_catcher(const char* msg)
{
// save mgs addr to r0 for avoid GCC optimisation
asm volatile ("ldr r0 , %[msg]" : : [msg]"m" (msg) : );
while(1)
asm volatile("nop");
}
__attribute__((__noreturn__)) inline void throw_exeption_catcher(int val)
{
// save mgs addr to r0 for avoid GCC optimisation
asm volatile ("ldr r0 , %[val]" : : [val]"m" (val) : );
while(1)
asm volatile("nop");
}
// переопределение обработчиков исключений
#include <bits/exception_defines.h>
#define THROW_CATCHER_ARG(ret_t,name,arg_t,arg_v) __attribute__((__noreturn__)) inline ret_t name(arg_t arg_v) {throw_exeption_catcher(arg_v);}
#define THROW_CATCHER_FMT(name) __attribute__((__noreturn__)) __attribute__((__format__(__printf__, 1, 2))) \
inline void name(const char* fmt, ...) {throw_exeption_catcher(fmt);}
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
THROW_CATCHER_ARG(void,__throw_bad_exception,void,) // Helper for exception objects in <except>
THROW_CATCHER_ARG(void,__throw_bad_alloc,void,) // Helper for exception objects in <new>
THROW_CATCHER_ARG(void,__throw_bad_cast,void,) // Helper for exception objects in <typeinfo>
THROW_CATCHER_ARG(void,__throw_bad_typeid,void,)
THROW_CATCHER_ARG(void,__throw_logic_error,const char*,msg) // Helpers for exception objects in <stdexcept>
THROW_CATCHER_ARG(void,__throw_domain_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_invalid_argument,const char*,msg)
THROW_CATCHER_ARG(void,__throw_length_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_out_of_range,const char*,msg)
THROW_CATCHER_ARG(void,__throw_runtime_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_range_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_overflow_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_underflow_error,const char*,msg)
THROW_CATCHER_ARG(void,__throw_ios_failure,const char*,msg) // Helpers for exception objects in <ios>
THROW_CATCHER_ARG(void,__throw_system_error,int,val)
THROW_CATCHER_ARG(void,__throw_future_error,int,val)
THROW_CATCHER_ARG(void,__throw_bad_function_call,void,) // Helpers for exception objects in <functional>
THROW_CATCHER_FMT(__throw_out_of_range_fmt)
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace __gnu_cxx
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
THROW_CATCHER_ARG(void,__verbose_terminate_handler,void,)
_GLIBCXX_END_NAMESPACE_VERSION
};
#endif /* __SUPC++_H__ */
supstl.h
CODE
#ifndef __SUPSTL_H__
#define __SUPSTL_H__
// KGP tools embedded SDK
// Chernov S.A. aka klen
// klen_s@mail.ru
#include <limits>
#include <algorithm>
#include <cstring>
extern "C" void* malloc( size_t );
extern "C" void free( void* );
namespace std
{
using std::size_t;
using std::ptrdiff_t;
/**
* @brief An allocator that uses malloc.
* @ingroup allocators
*
* This is precisely the allocator defined in the C++ Standard.
* - all allocation calls malloc
* - all deallocation calls free
*/
template<typename _Tp>
class KgpAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct rebind
{ typedef KgpAllocator<_Tp1> other; };
KgpAllocator() _GLIBCXX_USE_NOEXCEPT { }
KgpAllocator(const KgpAllocator&) _GLIBCXX_USE_NOEXCEPT { }
template<typename _Tp1>
KgpAllocator(const KgpAllocator<_Tp1>&)
_GLIBCXX_USE_NOEXCEPT { }
~KgpAllocator() _GLIBCXX_USE_NOEXCEPT { }
pointer
address(reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
const_pointer
address(const_reference __x) const _GLIBCXX_NOEXCEPT
{ return std::__addressof(__x); }
// NB: __n is permitted to be 0. The C++ standard says nothing
// about what the return value is when __n == 0.
pointer
allocate(size_type __n, const void* = 0)
{
if (__n > this->max_size())
std::__throw_bad_alloc();
pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp)));
if (!__ret)
std::__throw_bad_alloc();
return __ret;
}
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type)
{ free(static_cast<void*>(__p)); }
size_type
max_size() const _GLIBCXX_USE_NOEXCEPT
{ return size_t(-1) / sizeof(_Tp); }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up>
void
destroy(_Up* __p) { __p->~_Up(); }
#else
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_] allocator::construct
void
construct(pointer __p, const _Tp& __val)
{ ::new((void *)__p) value_type(__val); }
void
destroy(pointer __p) { __p->~_Tp(); }
#endif
};
template<typename _Tp>
inline bool
operator==(const KgpAllocator<_Tp>&, const KgpAllocator<_Tp>&)
{ return true; }
template<typename _Tp>
inline bool
operator!=(const KgpAllocator<_Tp>&, const KgpAllocator<_Tp>&)
{ return false; }
}
//-------- KGP utils & support ------------
#include <string> //need for basic_string
namespace kgp
{
//-------------------------------------------------------------------------------------
typedef std::basic_string<char, std::char_traits<char>, std::KgpAllocator<char> > emb_string; /// A string of @c char
class compare
{
public:
inline bool operator() (const char lhs, const char rhs) const {return lhs < rhs;}
inline bool operator() (const int& lhs, const int& rhs) const {return lhs < rhs;}
inline bool operator() (const float& lhs, const float& rhs) const {return lhs < rhs;}
inline bool operator() (const double& lhs, const double& rhs) const {return lhs < rhs;}
inline bool operator() (const char* lhs, const char* rhs) const {return strcmp(lhs,rhs) < 0 ;}
inline bool operator() (const emb_string& lhs, const emb_string& rhs) const {return lhs==rhs;}
};
}
using namespace std;
using namespace kgp;
#endif /* __SUPSTL_H__ */
__cxa_impl.h
CODE
/*
* __cxa_impl.h
*
* Created on: 28 янв. 2016 г.
* Author: klen
*/
#ifndef __CXA_IMPL_H__
#define __CXA_IMPL_H__
// KGP tools embedded SDK
// Chernov S.A. aka klen
// klen_s@mail.ru
#ifdef __cplusplus
extern "C" {
#endif
__extension__ typedef int __guard __attribute__((mode (__DI__)));
int __attribute__((__noreturn__)) inline __cxa_atexit(void (*func) (void *), void * arg, void * dso_handle)
{
throw_exeption_catcher();
}
int __attribute__((__noreturn__)) inline __cxa_guard_acquire(__guard* g)
{
throw_exeption_catcher();
//return !*g;
}
void __attribute__((__noreturn__)) inline __cxa_guard_release (__guard* g)
{
throw_exeption_catcher();
*g = 1;
}
void __attribute__((__noreturn__)) inline __cxa_guard_abort (__guard*)
{
throw_exeption_catcher();
}
void __attribute__((__noreturn__)) inline __cxa_pure_virtual()
{
throw_exeption_catcher();
}
#ifdef __cplusplus
}
#endif
#endif
__aeabi_impl.h
CODE
/*
* __aeabi_impl.h
*
* Created on: 28 янв. 2016 г.
* Author: klen
*/
#ifndef __AEABI_IMPL_H__
#define __AEABI_IMPL_H__
// KGP tools embedded SDK
// Chernov S.A. aka klen
// klen_s@mail.ru
#include "__cxa_impl.h"
#ifdef __cplusplus
extern "C" {
#endif
int inline __aeabi_atexit(void* object, void (*destroyer)(void*), void* dso_handle)
{
// atexit(f) should call __aeabi_atexit (NULL, f, NULL)
// The meaning of this function is given by the following model implementation...
return __cxa_atexit(destroyer, object, dso_handle);
// 0 ⇒ OK; non - 0 ⇒ failed
}
#ifdef __cplusplus
}
#endif
#endif /* __AEABI_IMPL_H__ */
заинклудте эти хидеры и реализуйте хоть как нибудь malloc/free, можно из newlib (он есть по умолчанию в сборке в виде libc)
и кстате да! забыл что тут же уменя есть класс emb_string - использовать как std::string