Am 19.06.2023 um 17:13 schrieb Jakob Hirsch:
> Hm, bisschen her...
>
> On 2023-01-24 14:36, Bonita Montero wrote:
>> habe ich das Problem, dass die Items mit hoher Frequenz dort eingefügt
>> werden und die Verarbeitungs-Semantik bei den Consumern so minimal ist,
>> dass diese auch mit der entsprechend hohen Frequenz abgebommen werden.
>
> Hm, es gibt m.W. dafür auch schlankere Konzepte (lockless P/C queue),
> vielleicht macht es das etwas einfacher.
Lockless queues haben sich nie durchgesetzt weil man die pollen muss,
was ein No-Go ist. Das Problem ist dann halt, dass der Producer auch
weg-schedult werden kann, dass der Consumer sich im Endeffekt dumm
und dämlich pollt bis der wieder mal an der Reihe war.
> Dafür gibt es üblicherweise System-Aufrufe, ...
Erzähl mir mal welche. Unter Windows kann ich den Basis-Takt aus der
Registry auslesen, unter Linux weiß ich nicht wo ich den unter /proc
finden kann. /proc/cpuinfo ist keine zuverlässige Quelle, denn da
findet man das ggf. nur im Prozessor-String.
> Unter Windows ist das QueryPerformanceCounter und
> QueryPerformanceFrequency, ...
Die ist auf x86ern immer 10MHz.
> unter Linux spuckt dir clock_gettime(CLOCK_MONOTONIC) ...
CLOCK_MONOTINIC_RAW bedient sich direkt am TSC.
>direkt die Werte aus (mit clock_getres könntest du dir auch noch die Auflösung
> holen).Und es gibt bestimmt auch genug libs für C++ die das schön in einer
> StopWatch-Klasse kapseln...
Ich hab jetzt mal geschaut wie effizient die Abfrage von
CLOCK_MONOTINIC_RAW auf meinem Linux-Rechner ist (AMD TR 3990X):
#include <iostream>
#include <iomanip>
#include <chrono>
#include <time.h>
using namespace std;
using namespace chrono;
int main()
{
auto start = high_resolution_clock::now();
constexpr uint64_t ROUNDS = 10'000'000;
timespec ts;
for( uint64_t r = ROUNDS; r--; )
clock_gettime( CLOCK_MONOTONIC_RAW, &ts );
double ns = (double)duration_cast<nanoseconds>(
high_resolution_clock::now() - start ).count() / ROUNDS;
cout << ns << endl;
}
Das zieht dann ca. 19ns, damit kann man leben.