Using the WBINVD Statement

I am trying to use the WBINV instruction for Linux to clear the L1 processor cache.

The following program compiles, but when you try to start it, a segmentation error occurs.

int main() {asm ("wbinvd"); return 1;}

I am using gcc 4.4.3 and running the Linux kernel 2.6.32-33 in my x86 field.

Processor Information: Intel (R) Core (TM) 2 Duo CPU T5270 @ 1.40 GHz

I built the program as follows:

$ gcc

$. / a.out

Segmentation error

Can someone tell me what I'm doing wrong? How to do it?

PS: I am running several performance tests and want the previous contents of the processor cache to not affect the results.

+6
source share
3 answers

Quoted from Intelยฎ 64 and IA-32 Software Developer's Guide Combined Volumes 2A and 2B: Instructions Kit Reference, AZ :

The WBINVD instruction is a privileged instruction. When the processor is in protected mode, the CPL of the program or procedure must be 0 to complete this instruction.

In other words, only kernel mode code is allowed to execute it.

EDIT: Previous SO discussion on clearing caches:

"C" programmatically flush L2 cache on Linux machines

How can I clear the processor cache in Windows x86?

How to clear L1 and L2 processor cache

https://stackoverflow.com/questions/3443130/how-to-clear-cpu-l1-and-l2-cache

+13
source

As user786653 wrote, wbinvd is a privileged instruction that segfaults in non-core code.

You should avoid using wbinvd for benchmarking, as it forces all kinds of bus lock cycles, serialization of the pipeline, and adds overhead from the kernel to the user space, etc., which most likely do not happen in your real program.

Therefore, your measurement will not be more accurate, it will contain all kinds of artifacts. Reading a data block in the size of the L2 cache will give better results.

You can read the source code into test programs for measuring clock cycles and monitoring performance to see how others got useful results.

+5
source

Actually, if you execute a privileged instruction in user space (ring 3), you get SIGILL with the subcode ILL_PRVOPC (signal (7) manpage).

SIGSEGV is reserved for memory-related exceptions, for example, choosing a virtual address that was not displayed, or trying to write to a read-only page.

Someone needs to tell Linux about posix standards.

-1
source

Source: https://habr.com/ru/post/893058/


All Articles