C/C++

Amikor az optimalizáló teszi futtathatóvá a hibás kódot

Fórumok

Valami ehhez hasonlót írtam:

*(uint16_t *) (buff + 241) = get_crc(buff, 241);

buff 4-re align-olt uint8_t buffer, illetve get_crc() uint16_t-vel tér vissza. -O1-gyel fordítva a kód hibátlanul fut, míg -O0-val lefordul, de futásidőben exception-t dob. Ami persze érthető. Nyilván -O0 esetén a fordító bután lefordította a páratlan címre történő egy gépi ciklussal történő 16 bites írást. Csak ugye itt meglehet, hogy két gépi ciklus kell, először egy 32 bites duplaszónak a felső byte-jába kell írni a 16 bites számunk alsó byte-ját, majd utána a következő 32 bites duplaszó alsó byte-jába írjuk a 16 bites számunk felső byte-ját. Little endian MIPS architektúra. Az optimalizáló érti, mire gondoltam, de ha csak bután lefordítjuk, akkor bizony ez nyilván exception. A programozónak látnia kell a hardware-t, annak működését is, nem elég az, hogy amit leírtunk, az elméletileg jó. Azt valódi hardware hajtja végre.

Egy kis DSP x86-on...

Fórumok

Sziasztok!

Egy kis digital signal processinghez kapcsolodo optimalizacios kerdes. Van egy effele programtoredek, amiben egesz aritmetikaval, mindenfele lookup-tablak hasznalataval es bufferek kezelesevel egy multiply-and-accumulate  jellegu belso ciklusmag futkoraszik:

 for ( i=0; i<nsample; i++ )
  {     [...]
        int     si,sq; 
 
        si=sq=0;

        for ( k=0,b_offset=2*i,sip=sip0; k<nnode; k++,b_offset+=2*nsample,sip++ )
         {      int     ci,cq,rot_cos,rot_sin;
       
                ci=2*(int)sib->sib_buffer[b_offset+0]-255;      /* 2*(k*nsample+i)+0 */
                cq=2*(int)sib->sib_buffer[b_offset+1]-255;      /* 2*(k*nsample+i)+1 */

                rot_cos=sif->sif_phase_shift_array[sip->sip_offset].re;
                rot_sin=sif->sif_phase_shift_array[sip->sip_offset].im;

                si += +rot_cos*ci-rot_sin*cq;
                sq += +rot_sin*ci+rot_cos*cq;
 
                sip->sip_offset = (sip->sip_offset+sip->sip_step)%sif->sif_phase_shift_length;
 
         }

        sif_out_buffer[0] = (si+255*PHASE_SHIFT_AMPLITUDE)/(2*PHASE_SHIFT_AMPLITUDE);
        sif_out_buffer[1] = (sq+255*PHASE_SHIFT_AMPLITUDE)/(2*PHASE_SHIFT_AMPLITUDE);
        sif_out_buffer += 2;
        [...]
  }

Itt a belso ciklusmag az erdekes, az `nnode` erteke a gyakoratban 8 lesz. A kerdes az az hogy vannak-e olyan SIMD utasitasok x86_64 alatt, amivel ez a ciklusmag jol kioptimalizalhato es/vagy a forditot ra tudjuk venni hogy hasznalja? Most nezem a objdump/disasm-ot, gcc-10.2.1 alatt, -O3-as optimalizacioval, es kb olyan mintha en irtam volna minimalis assembly rutinnal (oke, a LEA-s trukkok erdekesek). Ugy latom elsore hogy mar SSE2 alatt vannak pl 4x32 bites integer regiszterek, amikkel mar egy kis unroll felhasznalasaval eleg jol lehetne optimalizalni a fenti ciklust... de meg az is lehet hogy a ket ciklus felcserelesevel (nnode fut kivul, az nsamples pedig belul) megjobban kihasznalhatoak bizonyos SIMD/MAC utasitasok. 

Valamelyik internetekben azt olvastam hogy a forditok mar eleg okosak hogy felismerjek hogyha SIMD-del jol kioptimalizalhatoak az effele ciklusok, de ottan a peldak valos arithmetikara vannak kihegyezve. Itt meg integer aritmetika van.... opcionalisan annyi lehet a konnyites hogy a rot_cos, rot_sin ertekek valojaban i16-osak es a ci/cq ertekek pedig i8-asok, szoval akar valami PMADDWD is lehetne. 

Alapjaraton a fenti implementacio sem rossz a gyakorlatban, de hamar annyira nagy az arconporges az effele utasitaskeszletek irant, akkor kezdjuk el ertelmesen is hasznalni ;) 

[Ugy tunik megoldva] Valtozo elhelyezese abszolut cimre - GCC

Fórumok

Hali,

 

Szeretnek egy valtozot egy fix abszolut cimre tenni, a nehezites, hogy kizarolag a linker filebol, tehat a forrast (.c) nem akarom modositani (szoval pont a

int myvar __attribute__((section(".mySection")))

jellegu, a forrashoz hozzaadott dolgokat szertnem kikuszobolni).

Az architekture Cortex M4, de felteszem ez nagyjabol lenyegtelen.

A dolog hattererol: van egy (konstans) tomboket, stukturakat, ezek egymasbaagyazasat tartalmazo kod es a forras generalva van, kulso eszkozzel  - ezek a valtozok alapbol az applikacioba fordulnak (linkelodnek) bele, de ki kellene szervezni egy masik memoriacimre (egy file-ban van minden, amit az applikaciotol fuggetlenul kellene kezelni).

Az a resze mar megvan, hogy az egesz file egy megadott cimre kerul, viszont van egy "fo" valtozo (minden mas onnan indul). Viszont most az, hogy ez a valtozo hova kerul a szekcion belul, az a tobbi valtozo meretetol fugg (tehat kb. random). Ennek kellene fixhelyre kerulni, hogy az applikaco akkor is elerje, ha ez ezek a tombok, strukturak, etc. valtoznak.

Ezek a tombok, egyebek konstansok, szoval mindenkepp a flashbe kerulnek, csak ha nem specifikalom kulon, akkor egybe lesznek linkelve az alkalmazassal, nekem viszont egy kijelolt regioban kellene, hogy legyenek.

Nem tudom mennyire sikerult erthetoen fogalmaznom, ha kell, szivesen pontositok rajta.

Koszi

Vegulis csinaltam meg egy szekciot es a "fo" tombot attettem ebbe masik szekcioba, ahol csak az van, igy a cime fixalodott - meg nem probaltam ki, de eddig hasznalhatonak tunik.

Koszi mindenkinek az otleteket!

C String láma

Fórumok

Ritkán kell C-ben dolgoznom, leginkább mikrokontrollerek esetén, és akkor is zömében Arduino környezetben, ahol elég kényelmes String osztály érhető el.

Most azonban ESPIDF alapon kellene SVG-t generálnom, sok mérési adat megjelenítéséhez. Ehhez sok stringet kellene összefűznöm, és sprintf műveletekkel kitöltenem. Kerestem valami kényelmesebben kezelhető String osztályt, amit használhatnék, de nem találtam. Nekiállhatnék megírni, de olyan nehezen hiszem el, hogy ezt ne csinálták volna már meg ezren.

Tudtok valami kényelmesen használható C String osztályt, amit egyszerűen használhatnék? Fontos az append és az sprintf szerű formátumkezelés.

Pre- és post increment, decrement kifejezésekben

Fórumok

Nézzük az alábbi C kifejezést:

unsigned int *ptr;

if (ptr && *ptr && --*ptr == 0) timeout();

Egyfelől logikus, amit csinál. Megnézi, a pointer nem NULL-e, utána megvizsgálja, a ptr által mutatott unsigned int változó nagyobb-e nullánál, ha ez is igaz, csökkenti azt, majd megnézi, nullává vált-e. Ha igen, hívja a timeout() függvényt. Ha a ptr == NULL, vagy érvényes, de az általa mutatott változó nulla, akkor nem nyúl semmihez. Ha a ptr által mutatott érték nem nulla, csökkenti azt, de csak akkor hívja timeout() függvényt, ha elérte a nullát.

Ilyesmit szoktam írni, de egy pillanatra megrémültem. A -- precedenciája nagyobb, mint az && operátoré, így akár az is lehetne, hogy előbb minden vizsgálat nélkül csökkent, s csak utána értékeli ki az &&-ek által határolt tagokat. Bár, ha így lenne, szinte semmire sem lenne jó az, hogy amint a logikai kifejezésről tudható annak értéke, nem értékeli ki azt tovább, hanem kilép.

Gyakorlatiasan, az elvárt módon csinálja, de ha szigorúan nézem a precedenciát, akkor szerintem nem működne ez jól.

Qt 6.2.1 WASM SSL [Megoldva]

Fórumok

Az esélytelenek teljes nyugalmával kérdezném, sikerült-e valakinek SSL-t hegesztenie Qt 6.2.1 alá úgy, hogy azzal SSL-képes WebAssembly applikációkat állítson elő?

EMSDK: 2.0.14
Qt: 6.2.1
SSL: 1.1.1k
 

Megoldás: a hiba az volt, hogy a configure-t meghívó scriptben whitespace hiba volt és ezért eldobta a config egy részét, beleértve az SSL beállításokat.

C __randomize_layout talany

Fórumok

Sziasztok,

Tudna segiteni valaki esetleg, ha egy struktura ezzel van definialva __randomize_layout, tipikusan egy csomo a kernelben, akkor azt hoyan tudom reprodukalni mondjuk egy kprobe vagy tracepointba?

eBPF doksi szerint

Using tracepoints 3: bpf

BPF gives us a few ways to connect to tracepoints via different program types:

    BPF_PROG_TYPE_TRACEPOINT: this program type gives access to the TP_STRUCT_entry data available at tracepoint entry; i.e. the data assigned from the raw tracepoint arguments via the TP_fast_assign() section in the tracepoint definition. The tricky part with these tracepoints is the context definition must match that described in the TP_STRUCT_entry definition exactly. For example, in samples/bpf/xdp_redirect_cpu_kern.c the tracepoint format for xdp_redirect tracepoints is defined as follows

De ha randomizalt (The randstruct plugin randomly rearranges fields at compile time given a randomization seed.) akkor nem ertem, hogy fog osszetalalkozni a ketto.

Elore is koszi.

Milyen széles a wchar_t ?

Fórumok

Unicode karakterek Rust --> C közötti átadásakor belefutottam egy érdekes hibaüzenetbe:

warning: `extern` block uses type `char`, which is not FFI-safe
 --> src/main.rs:2:25
  |
2 |     fn teszt_c(charvec: *const char, len: usize);
  |                         ^^^^^^^^^^^ not FFI-safe
  |
  = note: `#[warn(improper_ctypes)]` on by default
  = help: consider using `u32` or `libc::wchar_t` instead
  = note: the `char` type has no C equivalent

Érdekességképpen a rovásírás is a 17 bites tartományban, konkrétan az U+10C80 - U+10CFF értékek között található, ahogy több távolkeleti ország karakterkészlete sem fér bele a 16 bites unicode-ba.
És akkor adódik a kérdés. Ha a Rust char típusa (unicode) az u32 széles, akkor a C nyelv wchar_t típusa az milyen széles valójában? Vannak olyan C fordítók, amely wchar_t típusa nem tudja befogadni a unicode értékeket?

Melyik C fordítóknál nem 32 bites a wchar_t?

Zárt tömb, nyílt tömb C++-ban [megoldva] + új kérdés

Fórumok

Azt szeretném kérdezni, hogy nem lehet, hogy mégis van
különbség az alábbi belépési pontok között?

int main(int argc, char** argv)

int main (int argc, char *argv[])

Külföldön azt mondták nekem, hogy nem ekvivalensek,
mégpedig a második ún. zárt tömb-re hivatkozik, míg
az első nyílt tömbre.

Avagy a ** nyílt tömbre mutató pointer, míg a
* tomb[] zárt tömbre mutató pointer.

 

Akkor is ha igaz, csak szemantikailag mondjuk, de szerintem

a C++ szintaktikailag nem ellenőrzi. Tényleg létezik így valami, hogy

zárt tömb vagy nyílt tömb?

A másik dolog az, hogy hogy lehet megcsinálni, hogy tetszőlegesen

hosszú argumentum legyen? Vagy nincs argc, hanem teljesen dinamikus?

Egyik munkahelyen már volt és valami ...-t kellett használni, de ott nem

gcc volt a fordító, hanem valami ipari fordító volt, talán IAR?

 

Közben megoldva:

// zárt tömb

    char a = array_place[7];

0041137E  mov  al,byte ptr [_array_place+7 (417007h)]
00411383  mov  byte ptr [a],al

// nyílt tömb
    char b = ptr_place[7];

00411386  mov  eax,dword ptr [_ptr_place (417064h)]
0041138B  mov  cl,byte ptr [eax+7]
0041138E  mov  byte ptr [b],cl

 

Szóval arról van szó, hogy mégis így volt: zárt tömbnél csak byte a pointer,

míg nyíltnál dword, mivel az a lehető leghosszabb is lehet.

 

Még kérdés lenne az, hogy van valami amit tilos programozáskor zárt tömbökkel

művelni, mert azt mindig nyílt tömbökkel kell. Ki az aki tudja?