shr | Simple , clean , and customizable social sharing buttons | Frontend Framework library
kandi X-RAY | shr Summary
kandi X-RAY | shr Summary
Simple, clean, customizable sharing buttons. Donate to support Shr - Checkout the demo.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
- Create a JSONP callback
- Wrapper function used for wrapping elements .
- Deep extend .
- Extract a domain .
- Creates an element .
- Test if element matches a selector
- Set all attributes
- Takes a number and formats it to a string
- Get all elements matching this selector
- debug debug function
shr Key Features
shr Examples and Code Snippets
Community Discussions
Trending Discussions on shr
QUESTION
I have implemented a Convolutional Neural Network in C and have been studying what parts of it have the longest latency.
Based on my research, the massive amounts of matricial multiplication required by CNNs makes running them on CPUs and even GPUs very inefficient. However, when I actually profiled my code (on an unoptimized build) I found out that something other than the multiplication itself was the bottleneck of the implementation.
After turning on optimization (-O3 -march=native -ffast-math
, gcc cross compiler), the Gprof result was the following:
Clearly, the convolution2D
function takes the largest amount of time to run, followed by the batch normalization and depthwise convolution functions.
The convolution function in question looks like this:
...ANSWER
Answered 2022-Mar-10 at 13:57Looking at the result of Cachegrind, it doesn't look like the memory is your bottleneck. The NN has to be stored in memory anyway, but if it's too large that your program's having a lot of L1 cache misses, then it's worth thinking to try to minimize L1 misses, but 1.7% of L1 (data) miss rate is not a problem.
So you're trying to make this run fast anyway. Looking at your code, what's happening at the most inner loop is very simple (load-> multiply -> add -> store), and it doesn't have any side effect other than the final store. This kind of code is easily parallelizable, for example, by multithreading or vectorizing. I think you'll know how to make this run in multiple threads seeing that you can write code with some complexity, and you asked in comments how to manually vectorize the code.
I will explain that part, but one thing to bear in mind is that once you choose to manually vectorize the code, it will often be tied to certain CPU architectures. Let's not consider non-AMD64 compatible CPUs like ARM. Still, you have the option of MMX, SSE, AVX, and AVX512 to choose as an extension for vectorized computation, and each extension has multiple versions. If you want maximum portability, SSE2 is a reasonable choice. SSE2 appeared with Pentium 4, and it supports 128-bit vectors. For this post I'll use AVX2, which supports 128-bit and 256-bit vectors. It runs fine on your CPU, and has reasonable portability these days, supported from Haswell (2013) and Excavator (2015).
The pattern you're using in the inner loop is called FMA (fused multiply and add). AVX2 has an instruction for this. Have a look at this function and the compiled output.
QUESTION
While testing things around Compiler Explorer, I tried out the following overflow-free function for calculating average of 2 unsigned 32-bit integer:
...ANSWER
Answered 2022-Mar-08 at 10:00Clang does the same thing. Probably for compiler-construction and CPU architecture reasons:
Disentangling that logic into just a swap may allow better optimization in some cases; definitely something it makes sense for a compiler to do early so it can follow values through the swap.
Xor-swap is total garbage for swapping registers, the only advantage being that it doesn't need a temporary. But
xchg reg,reg
already does that better.
I'm not surprised that GCC's optimizer recognizes the xor-swap pattern and disentangles it to follow the original values. In general, this makes constant-propagation and value-range optimizations possible through swaps, especially for cases where the swap wasn't conditional on the values of the vars being swapped. This pattern-recognition probably happens soon after transforming the program logic to GIMPLE (SSA) representation, so at that point it will forget that the original source ever used an xor swap, and not think about emitting asm that way.
Hopefully sometimes that lets it then optimize down to only a single mov
, or two mov
s, depending on register allocation for the surrounding code (e.g. if one of the vars can move to a new register, instead of having to end up back in the original locations). And whether both variables are actually used later, or only one. Or if it can fully disentangle an unconditional swap, maybe no mov
instructions.
But worst case, three mov
instructions needing a temporary register is still better, unless it's running out of registers. I'd guess GCC is not smart enough to use xchg reg,reg
instead of spilling something else or saving/restoring another tmp reg, so there might be corner cases where this optimization actually hurts.
(Apparently GCC -Os
does have a peephole optimization to use xchg reg,reg
instead of 3x mov: PR 92549 was fixed for GCC10. It looks for that quite late, during RTL -> assembly. And yes, it works here: turning your xor-swap into an xchg: https://godbolt.org/z/zs969xh47)
with no memory reads, and the same number of instructions, I don't see any bad impacts and feels odd that it be changed. Clearly there is something I did not think through though, but what is it?
Instruction count is only a rough proxy for one of three things that are relevant for perf analysis: front-end uops, latency, and back-end execution ports. (And machine-code size in bytes: x86 machine-code instructions are variable-length.)
It's the same size in machine-code bytes, and same number of front-end uops, but the critical-path latency is worse: 3 cycles from input a
to output a
for xor-swap, and 2 from input b
to output a
, for example.
MOV-swap has at worst 1-cycle and 2-cycle latencies from inputs to outputs, or less with mov-elimination. (Which can also avoid using back-end execution ports, especially relevant for CPUs like IvyBridge and Tiger Lake with a front-end wider than the number of integer ALU ports. And Ice Lake, except Intel disabled mov-elimination on it as an erratum workaround; not sure if it's re-enabled for Tiger Lake or not.)
Also related:
- Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? - and those 3 uops can't benefit from mov-elimination. But on modern AMD
xchg reg,reg
is only 2 uops.
GCC's real missed optimization here (even with -O3
) is that tail-duplication results in about the same static code size, just a couple extra bytes since these are mostly 2-byte instructions. The big win is that the a
path then becomes the same length as the other, instead of twice as long to first do a swap and then run the same 3 uops for averaging.
update: GCC will do this for you with -ftracer
(https://godbolt.org/z/es7a3bEPv), optimizing away the swap. (That's only enabled manually or as part of -fprofile-use
, not at -O3
, so it's probably not a good idea to use all the time without PGO, potentially bloating machine code in cold functions / code-paths.)
Doing it manually in the source (Godbolt):
QUESTION
I have written the following very simple code which I am experimenting with in godbolt's compiler explorer:
...ANSWER
Answered 2021-Dec-07 at 09:52The assembly seems to be checking if either num
or den
is larger than 2**32 by shifting right by 32 bits and then checking whether the resulting number is 0.
Depending on the decision, a 64-bit division (div rsi
) or 32-bit division (div esi
) is performed.
Presumably this code is generated because the compiler writer thinks the additional checks and potential branch outweigh the costs of doing an unnecessary 64-bit division.
QUESTION
I'm trying to use some simple I/O macros introduced in book "Assembler Language Programming for IBM Z System Servers" (Macros introduced in Appendix B section). But when I'm tryin to run the sample program, as soon as program reach the first macro system dump occurs. Also there is IEF686I in the output. I'm a student learning IBM assembly language and I'm not familiar with JCL and I don't know if I'm doing something wrong in it. Is the format of getting input and assigning the output area OK or I should do it in a different way? Here is the JCL:
...ANSWER
Answered 2021-Nov-18 at 11:15Something is wrong with your private macro PRINTOUT, or something is wrong with the stetup done before calling the macro in line 6 of your assembler source. I can't tell what it is, because you didn't provide details about that macro (others have suggested to rerun the job with PRINT GEN).
Lack of more information, this is my analysis of what happened:
This is the ABEND information printed in the joblog
QUESTION
I try to compile this code and use loop-specific pragmas to tell the compiler how many times to unroll a counted loop.
...ANSWER
Answered 2021-Nov-16 at 10:04https://godbolt.org/z/PT6T1691W it seems that -O2 -funroll-loops
does the trick, apparently that option needs to be on for the pragma to tell GCC how much to unroll. (Update: Or at least makes it have some effect. See comments, this doesn't seem to be a complete answer yet.)
(-funroll-loops
is not on by default unless you use -fprofile-use
, after doing a -fprofile-generate
run and running the program with representative input. It used to be on by default at -O3 a long time ago, but code bloat I-cache pressure usually made that worse for loops that aren't hot. This leads to bass-ackwards situations where the loop where GCC spends most of its time is a few instructions long with SIMD, but the fully-unrolled scalar prologue / epilogue are 10x the number of instructions, especially with wider vectors. Even with AVX-512, GCC usually just uses scalar for odd numbers of elements, not creating a mask. :/)
Fully unrolling loops is something GCC will do even at -O2
, at least for very small trip-counts. (e.g. up to 3 for an int
array p[i] += 1;
, with -O2 -fno-tree-vectorize
). https://godbolt.org/z/P5rvjYj1b
Fully-unrolling larger loops or higher trip counts (when the static code size would increase from doing so, perhaps) is not on by default at -O2
it seems. (GCC calls this peeling a loop in their tuning options/parameters, i.e. peeling all the iterations out of the loop so it goes away. -fpeel-loops
is on with -O3
, but not -O2
. Since GCC11, -fverbose-asm
no longer prints a list of optimization options enabled as asm comments.)
And BTW, it seems auto-vectorization is on by default at -O2
now in GCC trunk. Previously it was only on at -O3
, so that's interesting.
QUESTION
I have downloaded the street abbreviations from USPS. Here is the data:
...ANSWER
Answered 2021-Nov-03 at 10:26Here is the benchmarking for the existing to OP's question (borrow test data from @Marek Fiołka but with n <- 10000
)
QUESTION
With reference to to Ktor Pool implementation, may someone explain concept behind this implementation of pop and push. I tried to step through the code but I am still not wiser after studying the code.
Below is the code snippet that I am struggling to understand:
...ANSWER
Answered 2021-Oct-17 at 15:01There are two things that make this code look a bit unusual. The first is that it's designed to be accessed by multiple threads without using locks. The second is that it's using a single 64-bit value to store two 32-bit integers.
Lock freedomThis looks like some variation on a lock-free stack. It's designed to be accessed by multiple threads at the same time. The rough algorithm works like this:
- Get the old value and keep a note of it
- Determine what the new value should be
- Do an atomic compare-and-set to replace the value if and only if the value still matches the old value we saw at the start
- If the compare-and-set fails (i.e. somebody else changed the value while we were computing the new value), loop back to the start and try again
Lock-free algorithms like this can be preferable for performance in some types of application. The alternative would be to lock the entire stack so that while one thread is using the stack, all other threads have to wait.
Bit shiftingThe other thing that makes this code look more complicated is that it seems to be storing two values in a single variable. The index
value passed to pushTop
is a 32-bit integer. It then gets combined with a 32-bit incrementing counter, version
, before being stored. So top
is actually a 64-bit value where the first 32 bits are the 'version' and the last 32 bits are the 'index' that we passed in. Again, this compact storage format is probably a performance optimization.
If we add some comments to the code from pushTop
, it looks like this:
QUESTION
Step-out seems to be broken in Simics 2021.24. I did "enable-debugger" but it still doesn't work. Please see below:
...ANSWER
Answered 2021-Sep-27 at 13:29both the step-out and step-over-instruction requires debug information. You can add debug information with add-symbol-file. If you don't have the debug information, you will have to set a breakpoint or run until the instruction after the call. In this case, that would be one of:
bp.memory.run-until -x address = p:0x0dee41d1b
or
bp.memory.break -x address = p:0x0dee41d1b c
#IAmIntel
QUESTION
I am trying to write a shellcode in GNU asm for linux and i'm unable to call execve with arguments.
What i'm trying to do :
...ANSWER
Answered 2021-Aug-03 at 01:14You never pushed a pointer to the second argv string. push %rdx; push %rdi
pushes NULL and then the pointer to "/bin/ls"
, but there is no pointer to your "-laaaaa"
. You need one more push
in between the two. For instance:
QUESTION
I have a COBOL compile job which I didn't write and I am trying to understand how that works. It looks something like this:
...ANSWER
Answered 2021-Jul-29 at 14:49When a COPYBOOK is referenced it is selected based on the first dataset where the COPYBOOK is found. The compiler does not look at the dataset name where you are seeing the version number. The version number is a convention to control when new changes are introduced into the environment.
As an example, let's say a new version of MQ is installed the dataset can be changed to reference the newer version. This will depend on how the system programmers introduce change into the environment. Thats a more complicated answer beyond what your post is hitting on.
If you are "versioning" you would order the sequence of datasets in the concatenation. For instance, you might see something like:
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install shr
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page