Jump to content

Kā konkrēti izpaužas C++ valodas tuvums "dzelžiem".


Raimonds1
 Share

Recommended Posts

Ja runājam par GPIO vai citu interruptu apstrādi Linuxa kernelī, tad pat uz zem-gigaherca CPU, tas būs nanosekundēs.

 

Reku pat kāds pacenties un sazīmējis grafikus starp consjūmeru līmeņa RPi bez jebkādām optimizācijām, real-time kerneļiem un tevis pieminēto 8bitu mikrokontrolieri.

Starpība 10 vs 20 us. Ja optimizētu, tad nekādas starpības nebūtu, visdrīzāk būtu pat ātrāk.

Kam tieši tev vajag lielāku precizitāti?

histogram_of_response_time_measurements_

 

Pat līdz jūzerspeisam Pitonā events nonāk 200 - 300 micro sekunžu robežās.

histogram_of_response_time_measurements-

 

 

Tur jau galīgi jocīgam jābūt lai kautko taisītu Windowsā, iekš jūzerspeisa, uz x86, kam kautkāda saistība ar reālu laiku un vajag apstrādāt kādu signālu teiksim 10us robežās. Katrai problēmai savi risinājumi un rīki. Lasīt COM portu ar 1ms nobīdi šurpu/turpu pilnīgi neko nemaina un ir adekvāti.

 

 

Labots - AndrisBB
Link to comment
Share on other sites

Grossmeister
1 stundu atpakaļ, M_J teica:

Ja varētu runāt par tuvumu "dzelžiem" tad tikai un vienīgi assemblera gadījumā.

Exatly !

Labots - Grossmeister
Link to comment
Share on other sites

 

Negribas ar Tevi, Andri kašķēties, nešaubos, ka iekš procesora viss notiek nanosekundēs, tikai - kāds man no tā labums? Es tam vienkārši netieku klāt. Nemāku. Pa vidu ir operētājsistēma. Piemēram - ja gribēšu ieslēgt divus Mosfetus ar dažu nanosekunžu aizturi izmantojot, piemēram, Raspberry PI GPIO? Operētājsistēma man to, tā, pa vienkāršo, ļaus, jeb šī ideja vienkārši ir ārpus definīcijas apgabala? Ieslēgt/izslēgt gaismas diodi kaut kad -  ar +/- dažu desmitu milisekunžu precizitāti nav problēma, bet izdarīt prasīto ar nanosekunžu precizitāti? Vai ģenerēt divus sinhronus PWM signālus, tikai savstarpēji nobīdītus par dažām nanosekundēm? Nešaubos, ka dzelži to atļauj. Bet domāju, ka tā nav laba doma, mēģināt to realizēt uz Raspberry PI GPIO. Nesen uztaisīju nelielu programmiņu uz Raspberry PI, kas nolasa elektrības biržas cenas no internāta un slēgā patērētāju kontaktorus. Izmantojot  Raspberry PI GPIO. Izmantot GPIO sākotnēji likās laba doma, tagad tā vairs neliekas. Pārtaisu programmiņu, kur GPIO vairs netiks lietots.

Labots - M_J
Link to comment
Share on other sites

Ar ko tad īsti atšķirsies uzrakstīt to tavu GPIO slēdzelešanas kodu draiverī salīdzinot ar atsevišķu firmvāri priekš MCU?

Interruptus, lai kautko darītu varēsi saregulēt tieši tāpatās (prioritātes utt). Skaidrs ka kamēr koda izpilde nonāk līdz tavam draiverim, tur būs salīdzinoši mazliet ilgāka aizture kā uz MCU, jo vienkārši vairāk koda, kas savā ziņā atkal kompensējas ar lielākoties ātrāku CPU. Tapēc jāskatās kāds konkrētu MCU utt un kāds CPU. Ja prioritātes saliktas pareizi, tad jūzerspeiss un updeiti pagaidīs.

 

Pirms 53 minūtēm , M_J teica:

Es tam vienkārši netieku klāt.

Kam tu netiec klāt? Drivera kodu raksti tāpat kā jebkuru citu, nokompilē un ielādē draiveri. Viss. Nu OK, mazliet jāpastudē kā rakstīt draivera kodu, bet nekas sarežģitāks kā rakties pa MCU reģistriem.

 

Protams neviens nerakstīs draiveri, kas kautko dara ar nanosekunžu intervāliem, tas vienkārši noslogos CPU un tam neatliks laika darīt ko citu. Tapēc tagad gadndrīz visos CPU vēl nāk pa kādam iebūvētam MCU, ko vari izmantot tādiem mērķiem.

Bet ja runājam par milisekundēm, mikrosekundēm, tad tā arī nav nekāda problēma uz parasta CPU.

 

Rēķini arī to ka visām programmām userspeisā ir +- vienāda prioritāte, un programmu tur ir daudz.

Ja kerneļa schedulers ir nokonfigurēts ar 1ms time-slicingu, tad pat ja ļoti gribēsi, kernels nepārslēgsies biežāk uz tavu programmu kā tas intevāls, tāka neko precizāku par to arī nedabūsi. Realitātē kernels pat mēģinās godīgi sadalīt laiku starp tavu un citām programmām.

 

 

Labots - AndrisBB
Link to comment
Share on other sites

Pirms 38 minūtēm , AndrisBB teica:

Protams neviens nerakstīs draiveri, kas kautko dara ar nanosekunžu intervāliem, tas vienkārši noslogos CPU un tam neatliks laika darīt ko citu

Nu bet protams! Netaisos rakstīt nekādu draiveri nanosekunžu intervāliem. Tā "avene" man ir tikai priekš tam, lai nebūtu jāņem bleķa plāksne, jāurbj tajā caurumi un jāskrūvē tajos slēdžus un lampiņas un visādus "pulksteņus".  Tas taču ir grūti. Tagad slēdži un lampiņas ir uz ekrāna. Viegli pievienot jaunus slēdžus un lampiņas, izmest nevajadzīgos. Ar galveno tiek galā mikrokontrolieris. Ak jā - vēl avene slēdzas pie internāta un niekojas ar kaut kādu grāmatvedību.

  • Patīk 1
Link to comment
Share on other sites

Anonīms Alkoholiķis
pirms 6 stundām , Grossmeister teica:

Exatly !

Nē, 

Fpga vai pašam ar žileti un trulu naglu zīmēt silikonu.

Link to comment
Share on other sites

pirms 9 stundām , TOoMoOT teica:

WIndowsam Task Scheduler.

Velns 😁, kā šitas neienāca prātā... laikam vecs palieku 😁.

Dotajā gadīumā nav svarīgi, cik ms šur vai tur.

 

 

  • Haha 1
Link to comment
Share on other sites

Raimonds1

Vispār tas ir interesanti, kādas sarežģītības uzdevumus risina ar gigahercu procesoriem.

Aizsūtīt 2 skaitļus - laiku (minūti, datumu, gadu) un kaut kādu vērtību, 8 vai 16 bitu skaitli.

Saņemt tos 2 skaitļus ik pa minūtei (1440 x dienā) vai 480 x darba dienā.

Salikt tos stabiņā, grafikā, kaut kāda kolāžā.

 

Link to comment
Share on other sites

Pirms 37 minūtēm , Raimonds1 teica:

Salikt tos stabiņā, grafikā, kaut kāda kolāžā.

Kādā vēl kolāžā 😁?

Man vislabāk patika @M_J rakstītais par "slēdžiem, lampiņām un pulksteņiem'' 👍.

Link to comment
Share on other sites

pirms 5 stundām , Jurkins teica:

Velns 😁, kā šitas neienāca prātā... laikam vecs palieku 😁.

Dotajā gadīumā nav svarīgi, cik ms šur vai tur.

Tikai informācijai, varbūt kādam noder...

Influx TICK paketē ir tāds lielisks atsevišķi darbināms rīks "Telegraf" - datu iegūšanai, transformēšanai un noglabāšanai starp daudzām dažādām sistēmām.

https://www.influxdata.com/time-series-platform/telegraf/

Link to comment
Share on other sites

Anonīms Alkoholiķis

Kada veiktspeja uz rp2040?

Labots - Anonīms Alkoholiķis
Link to comment
Share on other sites

  • 3 months later...

Uzsildīsim mironi.😁

Pa brīviem brīžiem lasu gudras grāmatas 😁 (labāk būtu ēdis kodis)

 

const uint32_t d1{100};
const uint32_t &dr1 = d1;
const uint32_t &dr2 = d1;

std::cout << "d1 = " << d1 << std::endl;
std::cout << "dr1 = " << dr1 << std::endl;
std::cout << "dr2 = " << dr2 << std::endl;
std::cout << "&d1 = " << &d1 << std::endl;
std::cout << "&dr1 = " << &dr1 << std::endl;
std::cout << "&dr2 = " << &dr2 << std::endl;

 

Viss kārtībā. Rezultāts:

 

d1 = 100
dr1 = 100
dr2 = 100
&d1  = 0xda6dbff840
&dr1 = 0xda6dbff840
&dr2 = 0xda6dbff840

 

Tagad izdaram muļķību... pievienojam rindu:

 

(const_cast<uint32_t&>(dr1))++;

 

Rezultāts:

 

d1 = 100
dr1 = 101
dr2 = 101
&d1 = 0xda8d7ff8c0
&dr1 = 0xda8d7ff8c0
&dr2 = 0xda8d7ff8c0

 

Lasu, ka reference visu savu dzīves laiku norāda uz vienu un to pašu mainīgo. Nu tā arī ir - 0xda8d7ff8c0. Bet kāpēc 100 un 101?

:pooh_door:

 

Ja dara šādi:

 auto d2 = (const_cast<uint32_t&>(dr1))++;

tad:

 

d2 = 100

 

:hysteric:

 

Link to comment
Share on other sites

Anonīms Alkoholiķis

Labāk tiešām būtu kodis, bet vari vel paspet nezaudēt iekavēto.. 

 

Ja liec rindas bez konteksta kur ko iespraud, tad debago pats.

Link to comment
Share on other sites

Nu piedodiet...

#include<iostream>
#include<stdint.h>

int main(void)
{
    const uint32_t d1{100};
    const uint32_t &dr1 = d1;
    const uint32_t &dr2 = d1;
  
    std::cout << "d1 = " << d1 << std::endl;
    std::cout << "dr1 = " << dr1 << std::endl;
    std::cout << "dr2 = " << dr2 << std::endl;
    std::cout << "&d1 = " << &d1 << std::endl;
    std::cout << "&dr1 = " << &dr1 << std::endl;
    std::cout << "&dr2 = " << &dr2 << std::endl;

    auto d2 = (const_cast<uint32_t&>(dr1))++;
  
    std::cout << "d1 = " << d1 << std::endl;
    std::cout << "d2 = " << d2 << std::endl;
    std::cout << "dr2 = " << dr2 << std::endl;
    std::cout << "&d1 = " << &d1 << std::endl;
    std::cout << "&dr1 = " << &dr1 << std::endl;
    std::cout << "&dr2 = " << &dr2 << std::endl;

    return 0;
}

Rezultāts:

 

d1 = 100
dr1 = 100
dr2 = 100
&d1 = 0xa94b9ffd4c
&dr1 = 0xa94b9ffd4c
&dr2 = 0xa94b9ffd4c
d1 = 100
d2 = 100
dr1 = 101
dr2 = 101
&d1 = 0xa94b9ffd4c
&dr1 = 0xa94b9ffd4c
&dr2 = 0xa94b9ffd4c

Labots - Jurkins
Link to comment
Share on other sites

d1 arī ir 101, tik tas ka tu tur nodarbijies ar visādu figņu

auto d2 = (const_cast<uint32_t&>(dr1))++;

Un kompilātors tādu neparedz. Optimezējot abās vietās viņš izdrukā hārdkodētu #100

 

std::cout << "d1 = " << d1 << std::endl;
        movw    r1, #:lower16:.LC0
        movt    r1, #:upper16:.LC0
        movw    r0, #:lower16:_ZSt4cout
        movt    r0, #:upper16:_ZSt4cout
        bl      std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
        mov     r3, r0
        movs    r1, #100
        mov     r0, r3
        bl      std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned int)
        mov     r3, r0
        movw    r1, #:lower16:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        movt    r1, #:upper16:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     r0, r3
        bl      std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))

 

Link to comment
Share on other sites

Kapēc lai nevarētu? Tu paņem random adresi atmiņā un izmaini tās saturu, kā lai kompilātors par to zin?

Tikpat labi tu vari tai adresē ierakstīt ko vien vēlies.

 

const_cast<uint32_t&>(dr1) = 0xdeadbeef;

vai uzreiz

uint32_t *p = (uint32_t *)0xa94b9ffd4c;
*p = 0xdeadbeef;

 

Tu jau nemaini konstanti, bet saturu kautkādā atmiņas adresē. 

Nav jau tā ka tapēc ka tu kautko nodefinē par const, tad CPU to adresi kautkā īpaši aizsargās pret izmaiņām. Viss tas const tāds kompilēšanas laika mājiems kompilātoram, ka to nevajadzētu mainīt caur mainīgo, bet ja tu pa taisno maini, tad ko tur kompilātors var izdarīt. Viņš jau nezin kāda adrese tieši tai konstantei būs runtaimā, lai neļautu mainīt.

  • Patīk 1
Link to comment
Share on other sites

Uzliec static_cast un tev neļaus viņu mainīt.

Grūti iedomāties kur reālā dzīvē tev būtu jāizmanto const_cast. Tas vairāk kautkādos ekstrēmos gadījumos, kur tev jāstrādā jau ar esošu vecu sūdkodu.

Link to comment
Share on other sites

OK, paldies, skaidrs.

Tas, ka paņemot adresi pa taisno var ierakstīt, ko grib, bija skaidrs. Nesavilku abas lietas kopā.

Link to comment
Share on other sites

Nu ja tu izmanto static_cast, tad kompilators redzēs ka tu `kāsto` constanti, tapēc neļaus `kāstot` viņu uz ne-konstanti. const_cast vienkārši to ignorē un pārkāsto uz parastu pointeri, ko pēctam tu vari izmainīt.

Link to comment
Share on other sites

Par tiem "cast" ir ok, bet interesanti, kāpēc tā konstante c1 paliek kā bija 100, bet references 101. Ja, piemēram, uzraksta

2*c1, tad sanāk 200, bet 2*cr1 sanāk 202. Jeb kompilators "atceras", ka šamā bija 100?

 

Kā var vscode dabūt asmu, man tas disassembly logs ir tukšs. Debagojot pa soļiem arī.

Link to comment
Share on other sites

Es taks tev iepostoju kapēc. Tu viņu definēji kā const, tapēc compilātors iekompilē hārdkodētu vērtību. Pats saturs mainīgajā jau izmainās.

 

pirms 2 stundām , AndrisBB teica:
 movs    r1, #100

Viņš vienkārši visur kur tu izmanto d1 izprintē 100, jo tam nav jāmainās.

Pirms 14 minūtēm , Jurkins teica:

Kā var vscode dabūt asmu, man tas disassembly logs ir tukšs. Debagojot pa soļiem arī.

Pareizi kompilēt vajag, ar vajadzīgajiem flagiem.

Te vari debugot https://www.onlinegdb.com/online_c++_compiler

Ieliec te un apskaties kāda ir starpība start to kur tu printē d1 un kur tu printē pārējos

https://godbolt.org/

Kā arī kas izmainas ja tu noņem const no d1

Labots - AndrisBB
  • Patīk 1
Link to comment
Share on other sites

Raimonds1

Tāds jautājums.

Procesoram ir frekvence. Megaherci, gigaherci datoram.

 

Vai ir iespējams ārēji, ar signālu palaist un apstādināt skaitītāju, kas noskaita 2 vai 4 vai 15 pamatprocesora taktis un attēlo šo te skaitli. Start-Stop, 2 taktis no 4 gigahercu procesora.

 

Paldies par atbildi.

 

Kaut ko meklēju pats, bet tur pārsvarā ir par koda izpildes laiku

https://levelup.gitconnected.com/8-ways-to-measure-execution-time-in-c-c-48634458d0f9

tas nav tas

Link to comment
Share on other sites

pirms 2 stundām , AndrisBB teica:

Ieliec te

Jāpalasa kāda gudra grāmata 😁 par asmu. Zināšanas par avr asmu manāmi nepalīdz.

Link to comment
Share on other sites

Izveido kontu, vai pieraksties esošajā, lai komentētu

Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas

Izveidot jaunu kontu

Piereģistrējies un izveido jaunu kontu, tas būs viegli!

Reģistrēt jaunu kontu

Pierakstīties

Jums jau ir konts? Pierakstieties tajā šeit!

Pierakstīties tagad!
 Share

×
×
  • Izveidot jaunu...