169 похожих чатов

Изучаю как работает многопоточность в Julia, решил для примера написать

примитивное умножение матриц
Где я накосячил и как можно улучшить этот код?
Знаю, что в BLAS оно параллелится из коробки, но хотелось руками пощупать, а не готовое использовать.
function multiplyMatrices_oneThreadLoop(A::Matrix{Float64}, B::Matrix{Float64}, N::Int64)
C = zeros(N, N)
Threads.@threads for i in 1:N
for j in 1:N
for k in 1:N
C[i, j]+= A[i, k] * B[k, j]
end
end

end
return C
end

6 ответов

7 просмотров

Общие рекомендации сходу: * цикл по строкам всегда быстрее, чем цикл по колонкам (к вопросу о порядке вложенности циклов) * эффективно параллелить можно на количество потоков, не превышающее количество ядер. При этом, каждая задача должна быть достаточно длинной (ориентироваться на 50 мс и больше) * можно отключить проверку границ @inbounds

ну и, кстати, если циклы предполагают заполненине абсолютно всей матрицы С, то C = zeros(N, N) - это избыточная операция инициализации, которая тоже требует время. Лучше просто выделить память при помощи Matrix{Float64}(undef, N, N).

David-Golovatin Автор вопроса
Roman Samarev
ну и, кстати, если циклы предполагают заполненине ...

А разве использование undef не приведёт к погрешностям при подсчете C[i, j]?

David Golovatin
А разве использование undef не приведёт к погрешно...

но там же явная инициализаци C[i, j]+= A[i, k] * B[k, j]

David-Golovatin Автор вопроса
David Golovatin
А разве использование undef не приведёт к погрешно...

Судя по всему, я напоролся на data-race, так как если использовать undef при инициализации C, то в результирующей матрице начинают появляться NaN'ы

David Golovatin
Судя по всему, я напоролся на data-race, так как е...

нет, там же в коде +=. Я не заметил это. Тогда оптимальный вариант - считать в отдельную переменную то, что там на цикле с k и однократно записывать в C[i,j]. Заодно уйдёт лишний расчёт косвенных адресов

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
1
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Карта сайта