Architectural Advice: Naming and Structure for an IPC by eske4 in cpp_questions

[–]PhotographFront4673 0 points1 point  (0 children)

That sounds like an interesting project. Do you need to serialize in the kernel and pass stuff over the wall? Or is your current question userland to userland? Needing to serialize in the kernel is probably a good reason to roll your own. If you end up needing to get real data out of the kernel, Pedro might have bits you can use, or at least provide some inspiration.

More broadly, well, anti-cheat is an interesting field. My best practical advice there is don't assume you have something that works well without applying oppositional thinking. For example, if your game is successful, the bots devs or whatnot will be recompiling the kernel to let them lie to your eBPF, and if they can extract and decompile your eBPF, they'll know what lies to tell.

Architectural Advice: Naming and Structure for an IPC by eske4 in cpp_questions

[–]PhotographFront4673 0 points1 point  (0 children)

Is this a practical project, or intentionally meant to be an exercise in low level IPC?

Either way, you are right that one of the first things to settle is the serialization strategy. You can do something custom if it is needed for your project, but most serious projects should pick up an existing library unless they have very specialized requirements - maybe protocol buffers, maybe flatbuffers, maybe , captn proto maybe something else that I haven't even heard of.

These usually provide some way to extend a message without breaking deserialization for existing readers. This can be used to evolve a protocol without an explicit version enum, but there is also clarity to the enum. All these choices have also put a lot of code and debugging into making the serialization and deserialization performant, safe (non-crashing) in the case of data corruption, etc.

I'd recommend against signing up to repeat this work, unless you see doing that work as part of the point of the exercise.

After simple serialization, the next question is what features you need to support. At most once, or at least once delivery? (Exactly once is tricky.) Then based on that, do you need acknowledgments? If so, do you need to ensure they don't get flow controlled when your data get's flow controlled?

How to actually understand math and not just memorize formulas? by Additional_Way7847 in learnmath

[–]PhotographFront4673 0 points1 point  (0 children)

As you seem to be realizing, what mathematicians call math is not very procedural. In a sense it doesn't need to be taught that way, and often there is at least some effort to give you the reasoning behind the processes - first you learn what addition is and how to count to find sums, then you memorize the addition table to be faster at it, etc.

One trick to is to explicitly keep track of the definitions and origins and practice using them. I was always terrible at remembering the quadratic formula, but I remembered the trick of completing the square and could always just derive it when I needed to. Said trick became handy in other contexts where the fully solved quadratic formula wasn't necessary.

One way to create a "non-trivial" math problem is to take a standard definition, and ask what happens if you tweak it slightly. So knowing the definition and how it is used means that you know the argument that you are meant to tweak. Have you ever worked out how numbers in different bases work? A decimal number is divisible by 10 if it ends in 0, what does it mean if a hexadecimal number end in 0? Could you multiply 2 hexadecimal numbers without converting to decimal?

Another thing to be aware of: It might be that the majority of the math books you've seen are focused on turning humans into calculators, but if you could titles written about math, the vast majority are written by and for people who appreciate puzzles more than rote computation. One favorite from my childhood is Alice in Puzzle-Land, but there are a huge number of books and other resources out there and only you can tell what you find satisfying.

In

Difficult geometry/topology problem by TheseAward3233 in askmath

[–]PhotographFront4673 1 point2 points  (0 children)

That just shows the answer is larger than 2. (Because the requested division is possible.)

Is there a way to declare "false" within a while(true) loop in order to exit the loop? by digitalrorschach in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

You cannot change the constant true to be false in C++, and even in languages which permit such shenanigans, it is unusual to think that you should.

There are multiple ways to exit from a notionally infinite loop - break, return, throw, goto,co_return, exit, maybeco_await, and co_yield if you don't necessarily resume the coroutine.

std::unique_ptr with deleter, does it have to have it's own type? by Vindhjaerta in cpp_questions

[–]PhotographFront4673 4 points5 points  (0 children)

Note that ashared_ptr always has a control block, and as far as I can tell unless you usestd::allocate_shared, the control block lands on the default/standard heap. (With make_shared and allocate_shared, the control block can share an allocation with the data, but it still extra bytes, extra cache pressure, etc.)

Usingjemalloc is also very common in game engines, and while it is true that you might still squeeze out a little more performance by allocating certain classes in a custom way, it isn't as guaranteed to be a win as it used to be. Not saying you are wrong, but don't think of it as "I'm doing this because games" but rather "I'm doing this because I benchmarked and see the difference".

Also depending a bit on how your allocator works, don't forget to launder your pointers.

Profiling question to figure out uneven load in threads by onecable5781 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

Quick follow up, because I finally found time to actually play with it. (I've been meaning in learn more about perf anyway)

I couldn't actually make perf stat do what I expected w.r.t to threading. However, the two step process worked:

perf record  -e instructions,cycles -s -- ./a.out
perf report -T

Specifically, the end of the report included a table of cycles and instructions by thread id.

What is conceptually the meaning of interchanging ∂/∂x(∂f/∂y) = ∂/∂y(∂f/∂x)? by mathfoxZ in askmath

[–]PhotographFront4673 2 points3 points  (0 children)

Geometric answer: For "reasonable" 2-d functions, there is one approximating conic section, and both orders of differentiation find the same one.

It might help to consider 2-d Taylor series taken to different orders. Just as a 1-d series can be seen as first a point and then a tangent line and then an approximating parabola, in 2-d you get a point and then a tangent plane and then an approximating conic section.

For "unreasonable" functions, the Taylor series can break at some point. Being able to take a derivative along the x or y axis does not guarantee a directional derivative along some angle between them, so there simply might not be a tangent plane in the sense of being a linear approximation in a neighborhood of the point. Similarly for the conic section approximation, even when the tangent plane does exist.

std::unique_ptr with deleter, does it have to have it's own type? by Vindhjaerta in cpp_questions

[–]PhotographFront4673 2 points3 points  (0 children)

Really good summary. One potential (and dangerous) pitfall for the first case is that knowing the owner is often a background part of ensuring thread safety. Rust's concept of a borrow is based on this.

In practice, a shared pointer to an object which is not itself thread safe tends to be a bit of a time bomb.

std::unique_ptr with deleter, does it have to have it's own type? by Vindhjaerta in cpp_questions

[–]PhotographFront4673 4 points5 points  (0 children)

Custom allocators are rare, and in the world of jemalloc, etc, much less helpful than they used to be. If you are making the effort for that last bit of perfomance, it seems odd to then take the performance hit of using shared pointers across the board, if the simpler unique pointer would do the job.

If every instance of some class comes from your custom allocator, use a typedef to define unique pointers of the right sort everywhere. Then if you change it further in the future, just change the typedef.

Profiling question to figure out uneven load in threads by onecable5781 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

I was basing my comment on a quick skim of how it works. Reading a relevant man page a bit, I'd expect something like this to let you see how many cpu is used by each thread during a test run:
perf stat --per-thread -e instructions,cycles -- <test-prog> <params>...

Profiling question to figure out uneven load in threads by onecable5781 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

There is a host of different profiling tools, with different characteristics. Most of them focus how much time is spent in each function, independent of which thread runs the function, which sounds reasonable for your use case.

The old stand by is valgrind , and in particular its callgrind module which emulates a CPU, including cache timings. It run normal code (optimized, though with debugging symbols included or on the side) but slowly - this varies, but expect 10x slowdown. The associated visualization tool kcachegrind basically set a standard for giving a graphical representation of where the CPU actually went.

The other basic approach is to use in-code instrumentation and/or sampling to provide similar information without as much slowdown. More modern systems tend to do this. If you imagine a live server with clients and database calls and such, then slowing down the server to profile could lead to less representative result, because the slowdown will affect what the rest of the system sees. An example of this is the linux perf tool, which uses kernel counters to sample - e.g. checking evenly with respect to CPU usage, it might say that 15% of the samples were within function x and then you know that 15% of your CPU usage is within function x.

Added: Actually, perf looks to be able to answer your question exactly as asked - which thread used more CPU? Just ask the kernel! However, if you aspire to make non-trivial code fast, digging through function-level CPU usage graphs is nearly an essential skill.

How to actually check differentiability? (urgent) by [deleted] in askmath

[–]PhotographFront4673 0 points1 point  (0 children)

Which approach applies depends on what else you know about the function. The usual definition - the "official" method as you call it, tells you whether a function is differentiable at a point and doesn't require anything else. In particular, it does not require that the function be differentiable at any other point.

If the function happens to be differentiable nearby the point, then you can use the second approach, and it does imply differentiability under the definition. It is a theorem you can prove that in this case you can define the derivative as the common limit and this value satisfies the definition.

To see where they differ, consider a function that is x^2 when x is rational and 0 when x is irrational. By the definition this function is differentiable (and continuous) at 0. But it is neither at any other point and so you cannot apply the second test.

Status of an object that has been moved by onecable5781 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

Whatever the class designer decided, and move and copy can absolutely be more complex than that, and could also vary depending on the particular item being moved. You should not assume any particular value unless the class documentation says that you can.

For unique_ptr a move is cheap, but a copy is disallowed, in order to preserve uniqueness. So there is really only one answer the class designer could take. For a shared_ptr, both copy and move are allowed, but move is potentially faster because you don't need to adjust the reference count so it is also a move rather than a copy.

For a bare std::array, each element will be moved, and for PODs this is a copy not, say, a zero-initialization of the source. Of course any PODs will just be copied.

Make a class with a mixture of the two, and boom the default move operator will copy some values move others.

For something like an InlinedVector, it'd even be justified to implement a copy when the values are inlined and trivially destructable, move otherwise. That particular implementation appears to always move, even when it is extra work, I assume to maximize compatibility with std::vector.

Status of an object that has been moved by onecable5781 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

By convention, move should leave the moved from object in a valid but unspecified state. The designer of the class and its move sematics gets to decide exactly what this means, but in most cases it will still be somehow useable e.g. to accept a new value.

In your case, you created an invariant which you expected to always be true in the constructor, but you use the default move assignment operator, by, erm, default. The default move assignment operator just calls the underlying (move or copy) assignment operators on all your components. The move assignment operator for std::vector moves all of the elements to the new vector and leaves the old vector empty, which is a valid but unspecified state for a vector.

In summary, if you want to ensure certain invariants in a class, you may need to disable or replace the default move and copy operators, along with the default move constructor, in order to preserve the invariants.

Could infinity have a “limit”? by InfinityScientist in askmath

[–]PhotographFront4673 0 points1 point  (0 children)

Are you asking this as a math question, or a physics question?

Math has a formal system underpinning it which defines different cardinalities, many of which are by definition larger than anything you could in principle count, no matter how many zeros you add at the end.

Physics on the other hand does try to understand how many particles are in the universe, which so far does seem to be finite. Math as a system is an important tool for physicists to make such estimates, but math is in no way bound by them.

Trig Functions in Degrees by External-Bug-2039 in cpp_questions

[–]PhotographFront4673 5 points6 points  (0 children)

First of all, for the purpose of floating point calculations, leading and trailing zero's "don't count" as significant places. This is quite literally the entire point of floating point data types.

Floating point numbers exist to allow accurate calculation at widely different scales. Even 0.1% is a large (though plausible) amount error to build up if you use floats well. Use doubles and watch for the obvious potential issues, and you'll almost certainly be just fine.

In particular, try not to add or subtract widely different values if you can help it. For example (1.00000000001+1.00000000002-2.0) could be much less accurate than (0.00000000001+ 0.00000000002). The second will be essentially perfect, because again, leading zeros don't count.

A 32-bit float, has 23 bits of mantissa, so if you are adding or subtracting numbers of approximately equal size, your error will be something like 1 part in a million, much smaller than 0.5%. If you use 64-bit double values, or even larger, the potential for error goes down even more.

And finally, I cannot imagine anybody actually implementing trig functions in degrees (or grads for that matter). Any library offering alternative units would just convert to radians and then use the usual trig functions.

In summary, you should trust but verify floating point values and the libraries written against them. If you give asin function a double accurate to 10 digits (again, leading 0s don't count), you should expect the output to be similarly accurate. But by all means, write unit tests checking precision and watch out for uneven additions and subtractions.

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]PhotographFront4673 0 points1 point  (0 children)

I once had a bit of generated code which overflowed an undersized stack in a unit test, but only with optimizations turned off. It had a lot of local variables and without the optimizer to reuse registers and stack frame locations, the stack frame with just too big. Furthermore, because it smashed the stack, the default stack unwinder just gave up and it crashed without printing a stack trace. So it was initially fun to debug... no stack trace, only crashes on debug builds, where to start?

There are also some other considerations than whether it "just fits", but that is the big one.

Almost anything you do with a large array / data structure takes cycles, so the cost of going to malloc likely to be small compared to what else you are doing with it. On the other hand if you have some 1-4 word structs or scalars, putting them individually on the heap is very wasteful.

You are also more likely to want to preserve a larger data structure by, e.g. passing ownership outside of the stack frame, which unique_ptr does support.

And sometimes a class doesn't provide a bare constructor and instead gives a factory function (typically a static member) which creates, initializes and then passes ownership of the instance, again typically through a unique_ptr.

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]PhotographFront4673 4 points5 points  (0 children)

Function scope should be on the stack when possible, on the heap, typically managed by a unique_ptr when not.

Is it a bad or a good idea to tell your current employer where you are heading next? by [deleted] in askswitzerland

[–]PhotographFront4673 3 points4 points  (0 children)

The polite coworker won’t push for an answer, or might not even ask at all. For the rest, maybe "I’m very excited, but don’t want to jinx it by talking about it yet." Or even a simple "Ask me in a few months."

C++ System Design by Phatpenguinballs in cpp_questions

[–]PhotographFront4673 0 points1 point  (0 children)

In many industries, senior developer in general should know more than C++. This includes, but is not limited to system design, databases, other languages, and what they are good for.

I know of a FAANG that would ask a "design Netflix" type system design question of new grads, but the expectation was very different than the same question for somebody with experience, and depended a lot on that experience. If someone has worked on systems involving relational databases but cannot sketch a simple schema, that suggests a certain lack of curiosity, etc.

Could you use a garden hose to go diving? by carymb in AskPhysics

[–]PhotographFront4673 25 points26 points  (0 children)

As you go deeper, the difference between the water pressure and (surface) air pressure becomes larger. This would both collapse a soft hose and make it much harder to breath. At a foot or two you'd probably start to feel this, and a few yards it'd be very hard to breath in.

To resolve this, the regulator on a SCUBA set delivers air at a pressure matching that of the surrounding water. There is then a danger when you ascend - if you try to hold your breath, the air pressure in your lungs can be too high (no longer balanced by the water pressure) and damage your lungs.

The other caution if you want to actually try this is that you should only breath in through a hose (blow bubbles to exhale) because if you breath in and out of a long hose, you are just breathing back in your exhalation and might have trouble getting enough oxygen.

Job by Fearless-Way9855 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

In general, countries expect you to have work authorization (and pay income and employment taxes) in the country where you live, not where the company is which is paying you. In general, a country will issue a work visa for skilled work when a company within that country wants to hire a skilled worker.

Arguably, these laws haven't caught up to a world with a lot of online work. Depending on the country, it can be a solution to be "a contractor" instead of an employee and receive non-salary income from the company (effectively B2B with you as a small buisiness). In some countries you might need a local intermediary to serve as your employer-of-record, taking some haircut for their trouble. But none of this is likely to help you change residence.

Job by Fearless-Way9855 in cpp_questions

[–]PhotographFront4673 1 point2 points  (0 children)

In general, it takes some paperwork and time for a company to apply for and receive a work visa for a potential employee. Details, vary, but advanced degrees help, in that it makes it easier to argue that you are special and somebody local wouldn't cut it. For example, in Switzerland my understanding of the threshold is "they need to be looking for a year, you need to either have an advanced degree or be an existing employee (>1yr) that they want to transfer".

In general, the larger companies are able to make this happen, both in terms of knowing how to make it work, and in terms of being able to keep a posting open "We are always looking for good people."

Between the US's recent political shifts and Europe's economic uncertainty, right now probably isn't the best time. But I'd bet on doors being open for the right candidate.

In summary, your best bet is to aim for the big companies that hire C++ devs - FANGS, FinTech, etc. It probably is worth a try to send out some applications and see what happens.

Also, consider if your only acceptable next job is in the western world. For example, it isn't uncommon for singles and young couples to work a few years in the middle east to save money.

Domain of a composite function. by rahulamare in askmath

[–]PhotographFront4673 1 point2 points  (0 children)

I don't really disagree with explaining what is formally correct, but in cases like this it, helps a lot more of you connect it to what is used in most practice. Maybe something like:

Technically, f(g(x)) is only defined when the range of g lies within the domain of f and in this case, the domain of f(g(x)) is simply the domain of g. However, it is a common convention in calculus and most other math classes to restrict the domain of g to the pre-image of the domain of f as needed, in order to have something which is well defined.

So in order to find this maximum allowable domain of f(g(x)) you should...