- 1
- 2
- 3
- 4
- 5
- 6
// https://github.com/microsoft/PQCrypto-SIDH/blob/ebd1c80a8ac35e9ca2ef9680291a8a43b95a3bfa/src/random/random.c#L22
static __inline void delay(unsigned int count)
{
while (count--) {}
}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+1
// https://github.com/microsoft/PQCrypto-SIDH/blob/ebd1c80a8ac35e9ca2ef9680291a8a43b95a3bfa/src/random/random.c#L22
static __inline void delay(unsigned int count)
{
while (count--) {}
}
... guess what?
delay(0xFFFF); при -O3 ещё компилируется, а на delay(0xFFFFF); компилятор может зависнуть, потому что он пытается анроллить. Его ещё нужно проинструктировать, чтобы он не анроллил циклы.
Серьёзно? Какой багор )))
«Visual Studio» анроллит: https://gcc.godbolt.org/z/Bcbb2B. И если «[6000]» заменить на что-нибудь побольше — получится багор. Старые версии просто намертво зависали, а новые выдают многомегабайтные бинарники или, если переусердствовать, падают:
Проверил другие компиляторы.
icc инициализирует не инструкцией процессора, а тупо создаёт гигантскую инициализированную секцию в объектном файле (дохрена директив db).
clang и gcc выдают компактный код.
Watcom, Digital Mars, LCC создают гигантскую секцию из директив db.
Borland не понимает синтаксис { [6000] = 22}.
Pelles C, Orange C, tcc создают компактный код.
https://govnokod.ru/25216
А ещё у него есть рекурсивные структуры и lvalue-касты.
Это вам не питушарский сишный конпелятор, который считает себя умнее программиста и выкидывает целые ветки кода. Я максимум встречал оптимизацию щеледырок и свёртку констант.
Но за этим будущее. Правда, если выкидывает он эти ветки потому, что код эквивалентен, а не потому, что хочет наказать программиста за невнимательность. Именно поэтому я без языки без UB.
https://en.wikipedia.org/wiki/Assembly_language#Assembler
Some assemblers may also be able to perform some simple types of instruction set-specific optimizations. One concrete example of this may be the ubiquitous x86 assemblers from various vendors. Most of them are able to perform jump-instruction replacements (long jumps replaced by short or relative jumps) in any number of passes, on request. Others may even do simple rearrangement or insertion of instructions, such as some assemblers for RISC architectures that can help optimize a sensible instruction scheduling to exploit the CPU pipeline as efficiently as possible.[citation needed]
Я правильно понял, что реального примера не будет?
Стр. 100 :
> The volatile option instructs the assembler that subsequent load and store instructions may not be moved in relation to each other or removed by redundant load removal or other optimization. The volatile option is less restrictive than noreorder; it allows the assembler to move other instructions (that is, instructions other than load and store instructions) without restrictions.
https://sourceware.org/binutils/docs/as/Alpha-Directives.html
.setfeature
Enables or disables various assembler features. Using the positive name of thefeature enables while using ‘nofeature’ disables
...
volatile These control whether and how the assembler may re-order instructions. Accepted for compatibility with the OSF/1 assembler, but as does not do instruction scheduling, so these features are ignored.
Да и хуй с ним. Я про внешний цикл, который всё равно будет работать.
Может usleep() это слишком долго, ну там системный вызов, переключение процесса, а продрочить цикл можно без всяких системных вызовов
Я бы сделал в спин-локе yield
С «pthread_yield()» другой багор есть:
То есть если у нас есть десять ждущих потоков с приоритетом 5, «sched_yield()» из потока с 6 не даст ни одного кванта ждущим тредам. Для таких ситуаций надо юзать «sleep(0)».
This has absolutely nothing to do with cache coherence latencies or anything like that. It has everything to do with badly implemented locking.
I repeat: do not use spinlocks in user space, unless you actually know what you're doing. And be aware that the likelihood that you know what you are doing is basically nil.
There's a very real reason why you need to use sleeping locks (like pthread_mutex etc).
In fact, I'd go even further: don't ever make up your own locking routines. You will get the wrong, whether they are spinlocks or not. You'll get memory ordering wrong, or you'll get fairness wrong, or you'll get issues like the above "busy-looping while somebody else has been scheduled out".
And no, adding random "sched_yield()" calls while you're spinning on the spinlock will not really help. It will easily result in scheduling storms while people are yielding to all the wrong processes.
Sadly, even the system locking isn't necessarily wonderful. For a lot of benchmarks, for example, you want unfair locking, because it can improve throughput enormously. But that can cause bad latencies. And your standard system locking (eg pthread_mutex_lock() may not have a flag to say "I care about fair locking because latency is more important than throughput".
В STM32 нет никакого «user space». Поэтому я за STM32.
Да, это известно. Мало того yield может полностью игнорироваться шедулером.
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
Но это всяко лучше чем busy-wait.
Да, было недавно такое.
https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-yieldprocessor?redirectedfrom=MSDN
Хотя вполне допускаю что люди просто пытаются согреться, запуская холодными зимними вечерами busy wait.
Он слабовато греет, лучше что-нибудь с SSE считать пока ждёшь лочку.
> -O3
А ожидалось что-то другое?
-O1
If your contribution is more than 15 lines of code, you will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright.
Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement (Microsoft Contribution License Agreement.docx or Microsoft Contribution License Agreement.pdf), sign, scan, and email it back to [email protected]. Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request.