Finding the treetop locations from your point cloud data is typically just one part of the larger process known as individual tree detection & segmentation. To accomplish this, you can use a moving window operation to find the local maxima from a canopy height model raster (your Normalized DSM). This will be less computationally intensive and based on my experience similarly accurate to operations that infer the treetop locations directly from the point cloud, though you may want to test this for yourself.
One example of how you can implement this method is using the Focal Statistics tool from the spatial analyst toolbox in ArcMAPArcMap or ArcPROArcGIS Pro. Here are some other SE links you may find useful:
Finding local maxima with variable window search using ArcGIS Desktop?
Identifying individual trees and segmenting crowns from LiDAR CHM data?
Aside: Personally I like to use R, specifically the package lidR to perform these kind of operations. There are several algorithms you can use for every part of the pipeline, from removing noise from the initial cloud, decimating the points to speed up processing, detecting ground points, normalization, tree segmentation, crown delineation, and more. The creator of the package, @JRR is also quite active on this site in case you decide to go this route and need some support, so feel free to reach out to the community here. Best of luck and welcome to GIS SE.