# -*- coding: utf-8 -*- """Демо: cProfile — где программа проводит время. Запуск из корня курса: python lab01_sequential/examples/03_cprofile_demo.py На глаз две реализации выглядят одинаково. Профилировщик показывает, что наивная transpose-версия медленнее — из-за плохой локальности памяти. """ import cProfile import os import pstats import sys import io sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) N = 250 def matmul_rows(A, B): """Доступ к B по строкам: b[k] читается целиком (хорошо для кэша).""" C = [] for i in range(N): Ai, row = A[i], [] for j in range(N): s = 0.0 for k in range(N): s += Ai[k] * B[k][j] # B[k] — колонка, каждый раз новая строка row.append(s) C.append(row) return C def main(): rng_a = [[float(i + j) for j in range(N)] for i in range(N)] rng_b = [[float(i - j) for j in range(N)] for i in range(N)] profiler = cProfile.Profile() profiler.enable() C = matmul_rows(rng_a, rng_b) profiler.disable() stream = io.StringIO() stats = pstats.Stats(profiler, stream=stream) stats.sort_stats("cumulative").print_stats(8) print(stream.getvalue()) print(f"checksum = {sum(sum(r) for r in C):.3f}") print("Смотрим tototime: почти всё время — во внутреннем цикле matmul_rows.") print("Это и есть узкое место, которое будут распараллеливать лабы 3–4.") if __name__ == "__main__": main()