Найти - Пользователи
Полная версия: Помогите переделать програмку
Начало » Центр помощи » Помогите переделать програмку
1
GTSlade
import math
import datetime
import threading
 
print ("###### С потоками ######")
now_time = datetime.datetime.now()
print ("Начало в ", now_time)
 
sum1=[0.0, 0.0, 0.0, 0.0]
h=sum=0.0
def Inthread(a, b, n):
    h=(b-a)/n
    
    def Sintegral (fe, se, si):
        global sum1
        for i in range(int(fe), int(se)):
            t=a+i*h
            sum1[si]=sum1[si]+abs(math.sin(t))
 
    th1=threading.Thread(target=Sintegral, args=(1, n/4, 0))
    th2=threading.Thread(target=Sintegral, args=(n/4, n/2, 1))
    th3=threading.Thread(target=Sintegral, args=(n/2, 3*n/4, 2))
    th4=threading.Thread(target=Sintegral, args=(3*n/4, n, 3))
    
    th1.start()
    th2.start()
    th3.start()
    th4.start()
    th1.join()
    th2.join()
    th3.join()
    th4.join()
    
    global sum
    for i in range(4):
        sum=sum+sum1[i]
    integral = h*((math.sin(a)+math.sin(b))/2+sum)
    print("Integral:", float(integral))
    return integral
 
a=Inthread(0, math.pi/2, 10000000)
print ("Конец в " + str(datetime.datetime.now()))
now_time = datetime.datetime.now() - now_time
print ("Затрачено времени: " + str(now_time))
input()

Помогите переделать программу заменив threading на multiprocessing дабы ускорить ее выполнение.
(Нахождение интеграла синуса методом трапеций)
doza_and
GTSlade
дабы ускорить ее выполнение.
Если вам именно ускорить, то вам сюда: http://docs.scipy.org/doc/scipy/reference/tutorial/integrate.html

p.s.

с трудом верится что интегрирование синуса вас достало долгим выполнением.
GTSlade
В первом посте не стал вдаваться в подробности.
У меня курсовой проект, в котором изучается многопоточность в Питоне. Результатом должен быть вывод вида “Без потоков медленно, с потоками быстро”. В случае с threading'ом быстро не получается. А интеграл синуса это просто пример, на котором я рассчитывал разобраться.
doza_and
GTSlade
должен быть вывод вида “Без потоков медленно, с потоками быстро”
с минимальными усилиями это можно сделать так. При помощи numnpy считаете свой sin. потом разбиваете на участки и при помощи scipy считаете интегралы на участках. Тогда с тредами будет быстрее чем без них. Мультипроцессинг вам при этом не понадобится. Фишка в том что сами вычисления надо вынести в откомпилированный модуль, для того чтобы вам GIL не мешал.
py.user.next
Похоже, ему нужно не синус интегрировать, а просто многопоточную форму сделать, в которую потом можно будет вставлять любые операции.

GTSlade
У меня курсовой проект, в котором изучается многопоточность в Питоне. Результатом должен быть вывод вида “Без потоков медленно, с потоками быстро”.

Посмотри примеры https://docs.python.org/3/library/multiprocessing.html
yv84
➜  python.su  python3 t_24211_ask.py 
###### С потоками ######
Integral: 1.000000000000041
Затрачено времени: 0:00:08.956972
➜  python.su  python3 t_24211_answ.py
###### С потоками multiprocessing ######
Integral: 1.000000000000041
Затрачено времени: 0:00:01.779728
➜  python.su  pypy3 t_24211_ask.py 
###### С потоками ######
Integral: 1.000000000000041
Затрачено времени: 0:00:00.390492
➜  python.su  pypy3 t_24211_answ.py
###### С потоками multiprocessing ######
Integral: 1.000000000000041
Затрачено времени: 0:00:00.291700

t_24211_answ.py:
import math
import datetime
from multiprocessing import Process, Manager
print ("###### С потоками multiprocessing ######")
now_time = datetime.datetime.now()
print ("Начало в ", now_time)
sum1=[0.0, 0.0, 0.0, 0.0]
h=sum=0.0
def Inthread(a, b, n):
    h=(b-a)/n
    def Sintegral (fe, se, sum1, out):
        for i in range(int(fe), int(se)):
            t=a+i*h
            sum1=sum1+abs(math.sin(t))
        out[0] = sum1
        return
    global sum1
    manager = Manager()
    out_sum = []
    for i in range(4):
        out_sum.append(manager.list([sum1[i],]))
    processes = []
    for i, j in zip(range(4), [(1, n/4), (n/4, n/2),
                 (n/2, 3*n/4), (3*n/4, n)]):
        processes.append(Process(target=Sintegral,
            args=(j[0], j[1], sum1[i], out_sum[i])))
    for p in processes:
        p.start()
    for p in processes:
        p.join()
    global sum
    for i in range(4):
        sum=sum+out_sum[i][0]
    integral = h*((math.sin(a)+math.sin(b))/2+sum)
    print("Integral:", float(integral))
    return integral
a=Inthread(0, math.pi/2, 10000000)
print ("Конец в " + str(datetime.datetime.now()))
now_time = datetime.datetime.now() - now_time
print ("Затрачено времени: " + str(now_time))
doza_and
Интересное дополнение.

Для симметрии не хватает оценки вообще без потоков.

А вообще алгоритмы рулят а не количество процессоров…
Тут правда уже некорректно измеряется.
import numpy as np
from scipy.integrate import quad,simps
from time import clock
def integrand(x):
    return np.abs(np.sin(x))
t0=clock()
npoint=13
x=np.linspace(0, np.pi/2,npoint)
ans = simps(np.abs(np.sin(x)), dx=np.pi/2/(npoint-1))
t1=clock()
print "simps 1",ans,t1-t0
t0=clock()
ans, err = quad(integrand, 0, np.pi/2)
t1=clock()
print "quad",ans,t1-t0
t0=clock()
npoint=10000000
x=np.linspace(0, np.pi/2,npoint)
ans = simps(np.abs(np.sin(x)), dx=np.pi/2/(npoint-1))
t1=clock()
print "simps 0",ans,t1-t0
simps 1 1.00000163444 0.000127365258906
quad 1.0 0.000169417306416
simps 0 1.0 0.966470488785


К сожалению ваш код у меня не работает. :(

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\comp\Python33\lib\multiprocessing\forking.py", line 350, in main
    prepare(preparation_data)
  File "C:\comp\Python33\lib\multiprocessing\forking.py", line 457, in prepare
    '__parents_main__', file, path_name, etc
  File "C:\comp\Python33\lib\imp.py", line 180, in load_module
    return load_source(name, filename, file)
  File "C:\comp\Python33\lib\imp.py", line 119, in load_source
    _LoadSourceCompatibility(name, pathname, file).load_module(name)
  File "<frozen importlib._bootstrap>", line 584, in _check_name_wrapper
  File "<frozen importlib._bootstrap>", line 1022, in load_module
  File "<frozen importlib._bootstrap>", line 1003, in load_module
  File "<frozen importlib._bootstrap>", line 560, in module_for_loader_wrapper
  File "<frozen importlib._bootstrap>", line 868, in _load_module
  File "<frozen importlib._bootstrap>", line 313, in _call_with_frames_removed
  File "C:\PROJECTS\prjdocs\and\social\solution_method\simulation\cpp\bbb.py", line 39, in <module>
    a=Inthread(0, math.pi/2, 10000)
  File "C:\PROJECTS\prjdocs\and\social\solution_method\simulation\cpp\bbb.py", line 20, in Inthread
    manager = Manager()
  File "C:\comp\Python33\lib\multiprocessing\__init__.py", line 73, in Manager
    m.start()
  File "C:\comp\Python33\lib\multiprocessing\managers.py", line 486, in start
    self._process.start()
  File "C:\comp\Python33\lib\multiprocessing\process.py", line 111, in start
    self._popen = Popen(self)
  File "C:\comp\Python33\lib\multiprocessing\forking.py", line 216, in __init__
    cmd = ' '.join('"%s"' % x for x in get_command_line())
  File "C:\comp\Python33\lib\multiprocessing\forking.py", line 328, in get_command_line
    is not going to be frozen to produce a Windows executable.''')
RuntimeError: 
            Attempt to start a new process before the current process
            has finished its bootstrapping phase.
            This probably means that you are on Windows and you have
            forgotten to use the proper idiom in the main module:
                if __name__ == '__main__':
                    freeze_support()
                    ...
            The "freeze_support()" line can be omitted if the program
            is not going to be frozen to produce a Windows executable.
Traceback (most recent call last):
  File "C:\PROJECTS\prjdocs\and\social\solution_method\simulation\cpp\bbb.py", line 39, in <module>
    a=Inthread(0, math.pi/2, 10000)
  File "C:\PROJECTS\prjdocs\and\social\solution_method\simulation\cpp\bbb.py", line 20, in Inthread
    manager = Manager()
  File "C:\comp\Python33\lib\multiprocessing\__init__.py", line 73, in Manager
    m.start()
  File "C:\comp\Python33\lib\multiprocessing\managers.py", line 490, in start
    self._address = reader.recv()
  File "C:\comp\Python33\lib\multiprocessing\connection.py", line 251, in recv
    buf = self._recv_bytes()
  File "C:\comp\Python33\lib\multiprocessing\connection.py", line 307, in _recv_bytes
    [ov.event], False, INFINITE)
KeyboardInterrupt
yv84
doza_and
К сожалению ваш код у меня не работает.
Нет виндовс, чтобы найти причину, возможно:
if __name__ == "__main__":
    pass
doza_and

У вас что за питон?
Ну както так.
Вообще пиклиться могут только функции в глобальной области видимости. Я уже устарел?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from multiprocessing import Process, Manager,freeze_support
import math
import datetime
import threading
print ("###### С потоками multiprocessing ######")
now_time = datetime.datetime.now()
print ("Начало в ", now_time)
sum1=[0.0, 0.0, 0.0, 0.0]
h=sum=0.0
def Sintegral (a,h,fe, se, sum1, out):
    for i in range(int(fe), int(se)):
        t=a+i*h
        sum1=sum1+abs(math.sin(t))
    out[0] = sum1
    return
def Inthread(a, b, n):
    h=(b-a)/n
    manager = Manager()
    out_sum = []
    for i in range(4):
        out_sum.append(manager.list([0,]))
    processes = []
    for i, j in zip(range(4), [(1, n/4), (n/4, n/2),
                 (n/2, 3*n/4), (3*n/4, n)]):
        processes.append(Process(target=Sintegral,
            args=(a,h,j[0], j[1], sum1[i], out_sum[i])))
    for p in processes:
        p.start()
    for p in processes:
        p.join()
    global sum
    for i in range(4):
        sum=sum+out_sum[i][0]
    integral = h*((math.sin(a)+math.sin(b))/2+sum)
    print("Integral:", float(integral))
    return integral
if __name__ == "__main__":
    freeze_support()
    a=Inthread(0, math.pi/2, 10000)
    print ("Конец в " + str(datetime.datetime.now()))
    now_time = datetime.datetime.now() - now_time
    print ("Затрачено времени: " + str(now_time))
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.671875
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.687500
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.671875
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.687500
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.500000
###### С потоками multiprocessing ######
Начало в  2014-08-18 23:13:54.343750
Integral: 0.9999999979438331
Конец в 2014-08-18 23:13:54.828125
Затрачено времени: 0:00:00.484375
yv84
doza_and
Затрачено времени: 0:00:00.484375
Все хорошо, но a=Inthread(0, math.pi/2, 10000), вместо a=Inthread(0, math.pi/2, 10000000).

Глобальные переменные для мультипроцессинга не нужны, за все отвечает мультипроцессинг.Менеджер()

На моем пк
('simps 1', 1.0000016344385796, 0.00011400000000000299)
('quad', 0.9999999999999999, 0.000126000000000015)
('simps 0', 1.0000000000000291, 1.494825)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB