Z upstreamu GNOME Mutter byl zcela odstraněn backend X11. GNOME 50 tedy poběží už pouze nad Waylandem. Aplikace pro X11 budou využívat XWayland.
Byl publikován plán na odstranění XSLT z webových prohlížečů Chrome a Chromium. S odstraněním XSLT souhlasí také vývojáři Firefoxu a WebKit. Důvodem jsou bezpečnostní rizika a klesající využití v moderním webovém vývoji.
Desktopové prostředí LXQt (Lightweight Qt Desktop Environment, Wikipedie) vzniklé sloučením projektů Razor-qt a LXDE bylo vydáno ve verzi 2.3.0. Přehled novinek v poznámkách k vydání.
Organizace Open Container Initiative (OCI) (Wikipedie), projekt nadace Linux Foundation, vydala Runtime Specification 1.3 (pdf), tj. novou verzi specifikace kontejnerového běhového prostředí. Hlavní novinkou je podpora FreeBSD.
Nový open source router Turris Omnia NG je v prodeji. Aktuálně na Allegro, Alternetivo, Discomp, i4wifi a WiFiShop.
Na YouTube a nově také na VHSky byly zveřejněny sestříhané videozáznamy přednášek z letošního OpenAltu.
Jednou za rok otevírá společnost SUSE dveře svých kanceláří široké veřejnosti. Letos je pro vás otevře 26. listopadu v 16 hodin v pražském Karlíně. Vítáni jsou všichni, kdo se chtějí dozvědět více o práci vývojářů, prostředí ve kterém pracují a o místní firemní kultuře. Můžete se těšit na krátké prezentace, které vám přiblíží, na čem inženýři v Praze pracují, jak spolupracují se zákazníky, partnery i studenty, proč mají rádi open source a co
… více »Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za říjen (YouTube).
Jeff Quast otestoval současné emulátory terminálu. Zaměřil se na podporu Unicode a výkon. Vítězným emulátorem terminálu je Ghostty.
Amazon bude poskytovat cloudové služby OpenAI. Cloudová divize Amazon Web Services (AWS) uzavřela s OpenAI víceletou smlouvu za 38 miliard USD (803,1 miliardy Kč), která poskytne majiteli chatovacího robota s umělou inteligencí (AI) ChatGPT přístup ke stovkám tisíc grafických procesů Nvidia. Ty bude moci využívat k trénování a provozování svých modelů AI. Firmy to oznámily v dnešní tiskové zprávě. Společnost OpenAI také nedávno
… více »
typedef struct {
float** fDataA; //2D array of ...
...
}Data2;
typedef struct{
float a[3];
int b[4];
int c;
string string;
Data2 data2;
...
} Data;
int allocateData(Data **data,...){
*data = (Data*) malloc( pocetDat * sizeof(Data));
for(int y = 0;y < pocetDat; y++){
(*data)[y].data2.fDataA = (float**) malloc((*data)[y].data2.pocetDat2*sizeof(float*));
for(int i = 0;i < pocetDat2;i++){
(*data)[y].data2.fDataA[i] = (float*) malloc(pocetDat3*sizeof(float));
}
}
... //dalsi dynamicke alokace, overeni, jestli se to opravdu alokovalo...
}
int freeData(mainData **data){
for(int y = 0;y < pocetDat; y++){
for(int i = 0;i < pocetDat2; i++){
free((*data)[y].data2.fDataA[i]);
}
}
free(*data);
}
readData(Data **data,...){
...
allocateData(data,...);
...
//nactu hodnoty do data
...
}
main(){
Data *data;
...
readData(&data,...);
...
printf("integer %i",data[2586].b[4]);
freeData(&data);
}
*data = (Data*) malloc(spocitanaVelikost);?
Malloc je použit protože to původně bylo v C a až do teď jsem nějak nepřemýšlel v čem se vlastně tak liší od New.
Jenže Data a Data2 jsou struktury, ne třídy, takže jejich konstruktory použít nemůžu i když by se tím asi dost věcí zjednodušilo.
Vlasně možná by nemuseli být - budu k tomu muset udělat binding do Pythonu, který znám jen z rychlíku, ale předpokládal jsem, že bude vhodnější nechat data ve strukturách, než ve třídách, což asi nemusí být pravda. Struktura Data se předává mezi knihovnou a programem a nějak jsem předpokládal, že bude vhodnější předávat data ve struktuře a ne ve třídě, co je taky asi jedno....
fDataA[i*pocetDat2+y] místo fDataA[i][y],ale podle mě při takovém množství dat ta malá úspora paměti na úkor přehlednosti nemá cenu. Rychlost alokace je v porovnání s rychlostí načítání dat zanedbatelná. Jediný problém tuším v tom, že data nebudou v paměti za sebou, což nedokážu posoudit, jaký může mít vliv.
int allocateData(Data **data,...){
*data = new Data[pocetDat];
for(int y = 0;y < pocetDat; y++){
(*data)[y].data2.fDataA = new float*[pocetDat2];
for(int i = 0; i < pocetDat2; ++i){
(*data)[y].data2.fDataA[i] = new float[pocetDat3];
}
}
...
}
int freeData(Data **data,...){
for(int y = 0;y < pocetDat; y++){
for(int i = 0;i < pocetDat2; i++){
delete [] (*data)[y].data2.fDataA[i];
}
delete [] (*data)[y].data2.fDataA;
}
delete [] *data;
}
struct Data2
{
std::vector<std::vector<float>> fDataA;
// ...
};
struct Data
{
float a[3];
float b[4];
int c;
string string;
Data2 data2;
// ...
};
int allocateData(std::vector<Data>& data, ...)
{
data.resize(pocetDat);
for (size_t y = 0; y < pocetDat; ++y)
{
Data& dy = data[y];
dy.data2.fDataA.resize(pocetDat2);
for (size_t i = 0; i < pocetDat2; ++i)
{
dy.data2.fDataA[i].resize(pocetDat3);
}
}
// blabla
}
int freeData(std::vector<Data>& data)
{
// aneb vyser se na malloc a free
data.clear();
}
int freeData(std::vector<Data>& data)
{
// aneb vyser se na malloc a free
data.clear();
}
optimističtější varianta by musela vypadat asi takto nějak:
int freeData(std::vector<Data>& data)
{
data.clear();
// aneb vyser se na malloc a free
std::vector<Data> tmp;
data.swap(data);
}
Jinak vector určitě jo, nicméně pokud to má mít i malé paměťové nároky, tak bohužel jen jeden a počítat si to růčo a přistupovat k prvkům přes at(), ale zamyslel bych se nad tím, jestli mi opravdu vadí použít vector vector-ů při drobném navýšení nároků. Kdyby se jednalo o miliony a více záznamů, tak to má význam, ale tísíce znamená 10tis, což je asi 280KB navíc).
int freeData(std::vector<Data>& data)
{
// aneb vyser se na malloc a free
data.clear();
std::vector<Data>& tmp;
data.swap(tmp);
}
typedef struct{
float ttt[3][4][25];
}myrec;
std::vector<myrec> data;
g++ kuk.cpp -o kuk), ono vector je super, ale zrovna ve správě paměti se lehce naseká spousta chyb (platí pro celou stl).typedef struct {
u64 neco;
u8 neco2;
u8 neco3;
float pole1[4];
float pole2[4];
... /dalsi data - celkem 846B dat ulozenych vetsinou ve ve 4 prvkovych float polich s pevnou delkou
//nasleduje pet poli o ktere mi ted jde predevsim - na testovacich datech jsou tri
//z nich o velikosti 4*25 a dve prazdne. Maximalne muze v soucasne dobe mit kazde
//velikost 4*50. Velikost poli neznam v dobe kompilace, ale v dobe volani allocateData
//uz jo a nikdy se potom nemeni.
float *dulezitePole1; /**< 2D array of ... */
float *dulezitePole2; /**< 2D array of ... */
float *dulezitePole3; /**< 2D array of ... */
float *dulezitePole4; /**< 2D array of ... */
float *dulezitePole5; /**< 2D array of ... */
} Data;
allocateData(Data **data,...){
//pocetDat = pocet struktur Data je na testovacich datech 26000,
//v realu muze byt vyrazne min, ale i o dost vic.
*data = new Data[pocetDat];
for(int y = 0;y<pocetDat;y++){
(*data)[y].dulezitePole1 = new float[pocetDat21 * pocetDat3];
(*data)[y].dulezitePole2 = new float[pocetDat22 * pocetDat3];
(*data)[y].dulezitePole3 = new float[pocetDat23 * pocetDat3];
(*data)[y].dulezitePole4 = new float[pocetDat24 * pocetDat3];
(*data)[y].dulezitePole5 = new float[pocetDat25 * pocetDat3];
}
}
Když jsem místo float *dulezitePole1 zkoušel std::vector<float> dulezitePole1 a ve funkci allocateData použil dulezitePole1.resize(pocetDat21 * pocetDat3); byla spotrebovana pamet jen o 0.5 MB vetsi nez pri pouziti float* a new.
Jenže použití std::vector mi nepřineslo žádný viditelný užitek - stejně jsem si musel iterovat a pamatovat velikosti sám, protože dulezitePole1.size() je mi k ničemu. Navíc zde dochází k tomu, že většina polí je float[4] a 5 polí je std::vector, což je matoucí - tu knihovnu nebudu používat jen já.
Když jsem použil std::vector na všehny 4 prvkové pole floatů ve struktuře Data (je jich 50), tak paměťová náročnost vzrostla o 11,5MB.
int freeData(Data **data){
for(int y = 0;y < pocetDat; y++){
delete [] (*data)[y].dulezitePole1;
delete [] (*data)[y].dulezitePole2;
delete [] (*data)[y].dulezitePole3;
delete [] (*data)[y].dulezitePole4;
delete [] (*data)[y].dulezitePole5;
}
delete [] *data;
return 0;
}
Když místo resize použijete reserve, tak se sice paměť naalokuje, ale size bude ukazovat reálný počet prvků a přidávat pak budete pomocí push_back.
Na ta pole float[4] skutečně nemá cenu std::vector používat. Nevím co s těmi poli děláte, možná by zpřehlednění pomohl typedef či lépe nějaká obalující třída (pokud to jsou třeba quatermiony, tak se do obalující třídy dají přidat metody pro různé operace nad nimi, přetížit operátory a podobně).
Padesát čtyrprvkových polí ve struktuře mi trochu zavání špatným návrhem, opravdu to potřebujete takto udělat? Nestačilo by jedno padesátiprvkové pole tříd se čtyřmi floaty uvnitř?
Z mého pohledu má std::vector hlavní výhody v tom, že si nemusím udržovat počet prvků, v dealokaci a v čistotě kódu. Při vývoji velkých aplikací se mi to osvědčilo. Pokud tyto tři aspekty hodnotíte jinak, asi pro Vás nemá std::vector význam.
std::vector a v Qt s oblibou požívám QVector a podobné kontejnery, jen pro jejich požití v tomhle konkrétním případě nevidím moc důvod, ale je možné, že mi pořád něco uniká...
Jenže std::vector je příliš paměťově náročný, když mam 26000 struktur Data, který sice obsahujou dynamicky alokovaný pole, ale ve všechn 26000 případech odpovídající pole mají stejný rozměr (což sem asi měl zmínit dřív) - takže tady 26000*5 ukládám ve std::vector kromě vlstních dat to samý - velikost + další režii, což mi ve výsledku zvýší paměťovou náročnost a skoro mi to nepomůže.
Povídám místo std::vector.
Prostě si naprogramuj úsporné, efektivní a snadno použitelné 2D pole přesně takové, jaké potřebuješ. Transformace souřadnic jsem tu už viděl, jen to pěkně zabalit, aby se s tím dalo pracovat. Jeho prvky pak budou nějaké rozumné třídy/struktury/cokoliv, to už jsi tu snad už vyřešil o pár komentářů výše.
// vytvorenie pola objektov , !!pouziva def.konstruktor pre Data
Data *data = new Data[pocetDat];
// dealokovanie objektov Data
delete[] data;
// alokovanie pola smernikov (pointer) na typ float
(*data)[y].data2.fDataA = new float*[(*data)[y].data2.pocetDat2];
// alokovanie pola float-ov
(*data)[y].data2.fDataA[i] = new float[pocetDat3];
// dealokovanie
for(int y=;...;y++)
for(int i;...;i++)
delete (*data)[y].data2.fDataA[i] ;
delete (*data)[y].data2.fDataA;
Tiskni
Sdílej: