LINUX.ORG.RU
ФорумGames

NTSYNC для Wine включен в ядро Linux kernel 6.14

 ntsync, ,


0

2

В предстоящее ядро (6.14) интегрировали NTSYNC. Это драйвер обеспечивает большую совместимость игр запущенных через Wine, чем уже существующие Esync и Fsync.

https://www.gamingonlinux.com/2025/01/ntsync-for-proton-wine-now-in-linux-kernel-6-14-that-should-make-many-steamos-users-happy/

★★★★★
Ответ на: комментарий от cobold

Кто-то из местных тестил?

Тестил с последней версией модуля ядра и самыми свежими патчами к wine. Вроде все работает.

Какой профит?

В игры под wine я не играю, так что единственное что обнаружил, это при старте пишет:

wine: using fast synchronization.
Другие профиты не обнаружены, все работает как прежде.

arax ★★
()
Ответ на: комментарий от arax

Хотя нет, что то я вчера криво протестировал.
Вот на этом примере:

#include <Windows.h>
#include <thread>
#include <thread>
#include <vector>
#include <iostream>
#include <iomanip>

const int g_cRepeatCount = 100000;
const int g_cThreadCount = 16;

double g_shmem = 8;

HANDLE g_hMutex;

void threadFuncMutex() {
    for (int i = 0; i < g_cRepeatCount; ++i) {
        WaitForSingleObject(g_hMutex, INFINITE);
        if (i % 2 == 0)
            g_shmem = sqrt(g_shmem);
        else
            g_shmem *= g_shmem;
        ReleaseMutex(g_hMutex);
    }
}

void testRound(int threadCount)
{
    std::vector<std::thread> threads;

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncMutex));
    for (std::thread& thd : threads)
        thd.join();
    auto endMutex = std::chrono::high_resolution_clock::now();
    std::cout << "WaitForSingleObject/ReleaseMutex: " << std::setw(10) << std::chrono::duration_cast<std::chrono::microseconds>(endMutex - startMutex).count() / 1000 << " ms" << std::endl;
}

int main() {
    g_hMutex = CreateMutex(NULL, false, NULL);

    std::cout << "Iterations: " << g_cRepeatCount << std::endl;

    for (int i = 1; i <= g_cThreadCount; i = i * 2) {
        std::cout << "Thread count: " << i << std::endl;
        testRound(i);
        Sleep(1000);
    }

    if(g_hMutex)
        CloseHandle(g_hMutex);

    std::cout << "Shared variable value: " << g_shmem << std::endl;

    return 0;
}

Разница очевидна: https://0x0.st/88Tv.png

arax ★★
()
Ответ на: комментарий от arax

А вот интересно. Ранее (несколько лет назад) были всякие тесты игр где крутые игры работали также как в винде и даже чуть лучше. И что теперь? Они заработают в 5 раз быстрее?

mx__ ★★★★★
() автор топика
Ответ на: комментарий от mx__

очевидно тесты были на черрипикнутых играх, а большинство было медленнее. сейчас в которых уже было хорошо ничего не поменяется, остальные станут не сильно медленее или сравняются

anonymous
()
Ответ на: комментарий от mx__

С одной стороны те же mutex теперь работают быстрее чем в винде: https://0x0.st/88AM.png
Но я сомневаюсь, что это древнее winapi широко используется в современном коде.
Плюс пример кода который я привел, это абсолютно вырожденная ситуация, где происходит изнасилование mutex.

arax ★★
()
Ответ на: комментарий от arax

Ну вот и разрабы Wine подтянулись: https://www.phoronix.com/news/Wine-NTSYNC-Merge-Request

Через некоторое время wine засунут в ядро и будут как бы в нативе запускать виндовые проги прям из коробки …

… А потом подтянутся юристы из МС и прикроют эту лавочку.

mx__ ★★★★★
() автор топика
Ответ на: комментарий от mx__

… А потом подтянутся юристы из МС и прикроют эту лавочку.

Чтобы прикрыть, надо доказать прямое заимствование кода, насколько я понимаю. Вроде как, бодание Google-Oracle создало прецедент, что реализация API - не есть заимствование (если бодание закончилось, конечно, а то эта Санта-Бабара может быть вечной).

SkyMaverick ★★★★★
()
Ответ на: комментарий от SkyMaverick

Не очень понял. Про какое взаимоствование кода идет речь в случае Nintendo? Насколько я понял претензии там только из возможности просто запускать …

mx__ ★★★★★
() автор топика
Ответ на: комментарий от mx__

Но они подавали в суд, если я ничего не путаю, с мотивировкой, что эмуляторы обходят DRM (или что там у них защитное), что попадает под незаконное использование. Про возможность запускать игры, как таковые (про сам код), там ничего не говорилось.

SkyMaverick ★★★★★
()
Последнее исправление: SkyMaverick (всего исправлений: 1)
Ответ на: комментарий от SkyMaverick

Я не знаю всей механики этих эмуляторов, но к примеру эмуляторы Амиги просто позволяли грузить прошивку с оригинальных устройств и где ее брали, создателям эмуляторы было пофигу. А проги уже думали что их гоняют на оригинальной Амиге, и это сложно назвать обходом DRM.

Если игра написано под Windows only это еще вопрос, имеем ли право запускать ее не под Windows.

mx__ ★★★★★
() автор топика
Последнее исправление: mx__ (всего исправлений: 2)
Ответ на: комментарий от mx__

Если я правильно помню (что не факт), то игры шифрованы, и чтобы их запустить, нужно было использовать свистнутые ключи шифрования. За это юристы Nintendo и зацепились.

Т.е. они не смогли зацепить проект напрямую, т.к. альтернативные реализации не нарушают закон, если не используют заимствованный код. Но зацепились за то, что распространители взломанных игр рекомендуют именно этот продукт и решили притянуть их, как соучастников.

SkyMaverick ★★★★★
()

ntsync, esync, fsync

Как вайн\протон вообще выбирают через что работать?
Здесь Kron4ek писал:

Да, в Proton Esync и Fsync по умолчанию включены. Причем Fsync там имеет более высокий приоритет, так что если ядро его поддерживает, то Proton будет его использовать.

Ок, с этим понятно. У меня, судя по тому, что пришлось править лимит файловых дескрипторов для poe2, используется esync.
А как добавить поддержку Fsync в ядро, какая опция в конфиге?
С ntsync понятно - собрал 6.14-rc1, включил ntsync в виде модуля, и... что дальше? Как его задействовать?

sehellion ★★★★★
()
Ответ на: комментарий от sehellion

ntsync в виде модуля, Как его задействовать?

Как загрузить модуль и делать это автоматически при запуске я в курсе, если что. Вопрос в том, чтобы proton его использовал. Ждать?

sehellion ★★★★★
()
Ответ на: комментарий от sehellion

Не очень понял, то вы пишете работает, то нет.

Я нашел на форумах :

WINE_DISABLE_FAST_SYNC=0 for Wine 
and 
PROTON_USE_NTSYNC=1 for Proton. 

Только не понятно это будет работать или должно автоматом …

mx__ ★★★★★
() автор топика
Ответ на: комментарий от mx__

Я просто намешал сначала в кучу всё, а потом посмотрел.
Работает Fsync, но какие-то из лимитов точно правил. Какие именно и где не помню.
Использование же ntsync будет обозначаться в логе using fast sync, но нужно чтобы wine/proton были собраны с его поддержкой, а без этого переменные окружения нет смысла проставлять, т.к. эффекта не будет. Ну и в большинстве случаев и прироста ntsync против fsync вроде как и нет пока.

sehellion ★★★★★
()
Ответ на: комментарий от arax

Но SRW lock (добавленный ещё в NT 6.0) дополняет, а не заменяет CreateMutex и пр. Хотя бы потому, что mutex (winapi`шный, а не std::mutex) - кросс-процессный, а SRWLock - нет.

Аналогичное можно сказать и в отношении WaitOnAddress (добавлено в NT 6.2) и WaitForSingleObject.

MirandaUser2
()
Ответ на: комментарий от MirandaUser2

Причем тут вообще это?
Мной было сказано:

Но я сомневаюсь, что это древнее winapi широко используется в современном коде.

И действительно в коде использующем не древнючие msvc, std::mutex не ускоряется от включения ntsync и по прежнему значительнее медленнее чем под windows.
ntsync: https://0x0.st/8Pet.png
windows: https://0x0.st/8Pev.png

Код теста:

#include <Windows.h>
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <iomanip>

const int g_cRepeatCount = 10000000;
const int g_cThreadCount = 16;

double g_shmem = 8;

std::mutex g_mutex;

void threadFuncMutex() {
    for (int i = 0; i < g_cRepeatCount; ++i) {
        g_mutex.lock();
        if (i % 2 == 0)
            g_shmem = sqrt(g_shmem);
        else
            g_shmem *= g_shmem;
        g_mutex.unlock();
    }
}

void testRound(int threadCount)
{
    std::vector<std::thread> threads;

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncMutex));
    for (std::thread& thd : threads)
        thd.join();
    auto endMutex = std::chrono::high_resolution_clock::now();
    std::cout << "std::mutex lock/unlock: " << std::setw(10) << std::chrono::duration_cast<std::chrono::milliseconds>(endMutex - startMutex).count() << " ms" << std::endl;
}

int main() {

    std::cout << "Iterations: " << g_cRepeatCount << std::endl;

    for (int i = 1; i <= g_cThreadCount; i = i * 2) {
        std::cout << "Thread count: " << i << std::endl;
        testRound(i);
        Sleep(1000);
    }

    std::cout << "Shared variable value: " << g_shmem << std::endl;

    return 0;
}

arax ★★
()
Ответ на: комментарий от arax

Картинки с 0x0.st у меня почему-то не грузятся. :-( Но это не важно.

Какой вывод из этого эксперимента? Что std::mutex использует SRW lock? Так я это не подвергаю сомнению. Это в общем-то логично, т.к. кросс-процессность от std::mutex не требуется.

Меня удивляет утверждение о древности WaitForSingleObject и неиспользуемости в современном коде. Оно может и древнее, но никак не устаревшее (deprecated/obsolete), и вовсю используется для работы с эвентами и прочим.

MirandaUser2
()
Ответ на: комментарий от MirandaUser2

Какой вывод из этого эксперимента?

То что std::mutex как был тормозным под wine, так и остался, ntsync его не ускоряет.

Меня удивляет

Ну удивляет и удивляет, делов-то. Будешь значит теперь удивленным ходить :)

arax ★★
()